3

Page 724 , Chapter 25, The C++ Programming Language

A pointer used as a template argument must be of the form &of, where of is the name of an object or a function, or of the form f, where f is the name of a function. A pointer to member must be of the form &X::of, where of is the name of a member. In particular, a string literal is not acceptable as a template argument:

template<typename T, char∗ label>
class X {
    // ...
};
X<int,"BMW323Ci"> x1; // **error : string literal as template argument**
char lx2[] = "BMW323Ci";
X<int,lx2> x2; // OK: lx2 has exter nal linkage

Page 725 , Chapter 25, The C++ Programming Language

This becomes particularly useful when combined with a default template argument (§25.2.5); for example:

template<typename T, T default_value = T{}>
class Vec {
    // ...
};
Vec<int,42> c1;
Vec<int> c11; // default_value is int{}, that is, 0
Vec<string,"fortytwo"> c2;  // **I'm confused!**
Vec<string> c22; // default_value is string{}; that is, ""
Björn Pollex
  • 75,346
  • 28
  • 201
  • 283
JiangWei
  • 31
  • 2
  • 3
    Didn't you just answer your question yourself? – Kos Nov 19 '13 at 08:00
  • 1
    Check this: http://stackoverflow.com/questions/11788834/string-literal-as-template-argument – Blacktempel Nov 19 '13 at 08:01
  • No. why {{ X x1 }} is wrong, but {{Vec c2;}} is OK ? – JiangWei Nov 19 '13 at 08:03
  • Did you try to declare `template class X`? – πάντα ῥεῖ Nov 19 '13 at 08:11
  • Have you tried to compile this? If so, which compiler have you used? Because [it doesn't work on Ideone](http://ideone.com/OOYbmx). – Björn Pollex Nov 19 '13 at 08:38
  • 1
    The issue with string literals is that when you use `"abcd"` in two or more translation units, there may be one copy of `"abcd"` in the executable file or there may be more than one. If using a string literal as a template argument was legal, `my_template<"abcd">"` might name the same type everywhere, or it might name to different types in two different translation units. This would be a portability nightmare. – Pete Becker Nov 19 '13 at 16:34
  • 1
    Vec c2; This is an error in this book. – YNG Nov 29 '17 at 12:54

2 Answers2

2
template<typename T, T default_value = T{}>
class Vec {
    // ...
};
Vec<string,"fortytwo"> c2;
Vec<string> c22;

Neither declaration involving string is legal at all.

14.1/4:

A non-type template-parameter shall have one of the following (optionally cv-qualified) types:

  • integral or enumeration type,

  • pointer to object or pointer to function,

  • lvalue reference to object or lvalue reference to function,

  • pointer to member,

  • std::nullptr_t.

14.1/7:

A non-type template-parameter shall not be declared to have floating point, class, or void type.

Community
  • 1
  • 1
aschepler
  • 70,891
  • 9
  • 107
  • 161
0

A string literal is not acceptable as a template argument. With the first template, you have to declare a char array to be used as template argument.

With the second template, the "fortytwo" isn't a string literal. Instead, it is a std::string.

Deidrei
  • 2,125
  • 1
  • 14
  • 14
  • The template argument `"fortytwo"` is still a string literal. There's a difference in the type of the template parameter it initializes, though.... – aschepler Nov 19 '13 at 08:14
  • Yes. Its type is inferred from the first one (template T). – Deidrei Nov 19 '13 at 08:16
  • An argument for a template value parameter can be (§iso.14.3.2): • An integral constant expression (§10.4) • A pointer or a reference to an object or a function with external linkage (§15.2) • A nonoverloaded pointer to member (§20.6) • A null pointer (§7.2.2) – JiangWei Nov 19 '13 at 08:16