Some const char * are unavailable at compile time?

早过忘川 提交于 2019-11-30 17:11:43
James Kanze

The instantiation variable of a template needed to have external linkage, and const was implicitly internal linkage. So you have to write:

extern char const constMessage[] = "Const message";

(Another alternative would be for it to be a static class member. Static class members always have external linkage.)

The case of string literals is in some ways similar: their type is char const[]. But it's even worse: template instantiations (at least the early ones) need a name, and a string literal doesn't have one. Even more to the point, it's unspecified whether identical string literals are the same object or not, so in the following:

template <char const* m>
struct Toto { char const* f() const; };

Toto <"titi"> t1;
Toto <"titi"> t2;

it would be unspecified whether t1 and t2 had the same type or not.

From the c++11 standard §14.3.2.1

Template non-type arguments

A template-argument for a non-type, non-template template-parameter shall be one of:

  1. for a non-type template-parameter of integral or enumeration type, a converted constant expression (5.19) of the type of the template-parameter; or
  2. the name of a non-type template-parameter; or
  3. a constant expression (5.19) that designates the address of an object with static storage duration and external or internal linkage or a function with external or internal linkage, including function templates and function template-ids but excluding non-static class members, expressed (ignoring parentheses) as & id-expression, except that the & may be omitted if the name refers to a function or array and shall be omitted if the corresponding template-parameter is a reference; or
  4. a constant expression that evaluates to a null pointer value (4.10); or
  5. a constant expression that evaluates to a null member pointer value (4.11); or
  6. a pointer to member expressed as described in 5.3.1; or
  7. an address constant expression of type std::nullptr_t.

To your questions:

Why the namespace_const_message and const_message aren't available at compile-time and thus forbidden in the print template function?

That's why constexpr exists. They can be used where it's needed compile-time evaluation, thus available to be template-arguments.

Is my guess about the string literals correct?

There is a note about this right after the arguments:

Note: A string literal (2.14.5) does not satisfy the requirements of any of these categories and thus is not an acceptable template-argument.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!