假设我们有
template <const char*>
struct A{};
// static storage
const char a[] = "asd";
const char* p = "asd";
此实例化
A<a>{};
对编译器没问题。这是可以理解的 - 数组a
衰减指向第一个元素。但是,如果我们使用A
实例化p
A<p>{};
编译器发出错误:
错误:类型为'char *'的非类型模板参数不是常量表达式
为什么标准不允许指定类型const char*
的命名变量或只是字符串文字"asd"
,它是btw左值本身,作为模板参数?
答案 0 :(得分:11)
数组a
是一个常量字符数组,它在编译时已完全初始化,并且还可以通过编译器获取已知的内存地址,这就是为什么它可以衰减到模板中的指针。
但p
是一个常量字符数组的指针,但指针本身不是编译时常量,可以更改为指向其他字符串,它是不在编译时初始化,但是在链接时(编译后发生)或程序加载到内存时。 p
的地址在编译时是已知的,但不是字符串文字p
指向的地址。
为了扩展在编译时不知道字符串文字的地址的原因,这是因为它被编译器代码生成器放入一个特殊的只读段,然后将该只读段与链接时来自其他translation units的只读段。这就是为什么直到链接时(最早)才能知道字符串文字的最终地址。
答案 1 :(得分:0)
如果您想象respond_to do |format|
format.json { render json: requests, include: '*', each_serializer: PortalRequestSerializer, scope: current_contact }
end
respond_to do |format|
format.json { render json: requests, include: '**', each_serializer: PortalRequestSerializer, scope: current_contact }
end
被某个函数初始化,可能有助于理解为什么A<p>{};
不被允许的原因
p
其中const char* p = getP();
通过某些运行时数据确定其结果,例如,通过读取配置文件。