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

Bik*_*eev 8 c++ templates

让我们说我们有

template <const char*>
struct A{};

// static storage
const char a[] = "asd";
const char* p = "asd";
Run Code Online (Sandbox Code Playgroud)

这个实例化

A<a>{};
Run Code Online (Sandbox Code Playgroud)

对编译器没问题.这是可以理解的 - 数组a衰减指向第一个元素.但是,如果我们实例Ap这样的

A<p>{};
Run Code Online (Sandbox Code Playgroud)

编译器给出错误:

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

为什么标准不允许指定类型的命名变量const char*或只是字符串文字"asd",即btw左值本身,作为模板参数?

Som*_*ude 12

该数组a是一个常量字符数组,它在编译时已完全初始化,并且还通过编译器获取已知内存地址,这就是为什么它可以衰减到模板中的指针.

但是p指向常量字符数组的指针,但指针本身不是编译时常量,可以更改为指向其他字符串,并且在编译时不会初始化,而是在链接时(或者在编译之后或程序加载到内存中时发生.地址p在编译时已知,但不是字符串文字的地址p.


为了扩展在编译时不知道字符串文字的地址的原因,这是因为它被编译器代码生成器放入一个特殊的只读段,然后该只读段与读取器组合在一起.链接时只有来自其他翻译单元的段.这就是为什么直到链接时(最早)才能知道字符串文字的最终地址.