Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;非类型模板参数const char*_C++_Templates - Fatal编程技术网

C++ C++;非类型模板参数const char*

C++ C++;非类型模板参数const char*,c++,templates,C++,Templates,假设我们有 template <const char*> struct A{}; // static storage const char a[] = "asd"; const char* p = "asd"; 编译器给出一个错误: 错误:“char*”类型的非类型模板参数不是常量表达式 为什么标准不允许指定类型为const char*的命名变量,或者只指定字符串literal“asd”,顺便说一句,它本身就是左值,作为模板参数?数组a是一个常量字符数组,它在编译时被完全初始化,

假设我们有

template <const char*>
struct A{};

// static storage
const char a[] = "asd";
const char* p = "asd";
编译器给出一个错误:

错误:“char*”类型的非类型模板参数不是常量表达式


为什么标准不允许指定类型为
const char*
的命名变量,或者只指定字符串literal
“asd”
,顺便说一句,它本身就是左值,作为模板参数?

数组
a
是一个常量字符数组,它在编译时被完全初始化,并且编译器也会获得一个已知的内存地址,这就是为什么它会衰减为模板中的指针

但是
p
是一个指向常量字符数组的指针,但指针本身不是编译时常量,可以更改为指向其他字符串,它不是在编译时初始化的,而是在链接时(编译后发生)或程序加载到内存时初始化的。编译时已知
p
的地址,但不知道字符串literal
p
指向的地址



为了进一步说明编译时字符串文本的地址未知的原因,这是因为编译器代码生成器将其放入一个特殊的只读段中,然后在链接时将该只读段与另一个只读段合并。这就是为什么字符串文字的最终地址在链接时(最早)才能知道的原因。

这可能有助于进一步理解为什么
A{}p
由某个函数初始化,则不允许使用code>

const char* p = getP();

其中,
getP()
通过一些运行时数据来确定其结果,例如,通过读取配置文件。

我不认为它与左值有关,因为
p
没有精确的内存位置,但
a
有。这与
模板结构X{}没有什么不同;int p=5;XX谢谢,有道理。但为什么即使我使用constexpr const char*p=“something”?它也不起作用@比基涅夫同样的问题,在编译时,当模板需要字符串时,无法计算字符串的位置。非常感谢!回答得很好
A<p>{};
const char* p = getP();