N4527 14.6 [温度] / p8
如果由于不依赖模板参数的构造而导致模板定义后的假想实例化不正确,则程序不正确;无需诊断。如果在假设的实例中这种构造的解释与在模板的任何实际实例中对相应构造的解释不同,则程序格式错误;无需诊断。[注意:在以下情况下可能会发生这种情况:
(8.1)—在非依赖名称中使用的类型在定义模板时是不完整的,但在执行实例化时是完整的,或
(8.2)—实例化使用在定义模板时尚未定义的默认参数或默认模板参数,或
(8.3)-模板实例化中的常量表达式求值(5.20)
(8.3.1)—整数或无范围枚举类型的const对象的值,或者
(8.3.2)— constexpr对象的值,或者
(8.3.3)-参考值或
(8.3.4)-constexpr函数的定义,
并且在定义模板时未定义该实体,或者
那么,这些代码格式不正确吗?
代码1:
extern double b;
template<class T>
void f(T=b){}
void g(){
f<double>();//ill-formed or not?
}
double b = 0;
void h(){
f<double>();//ill-formed or not?
}
代码2:
//translation 1
extern double b;
template<class T>
void f(T=b){}
void g(){
f<double>();//ill-formed or not?
}
//translation 2
double b = 0;
模板中的非依赖引用所引用的实体的各种特征可以在定义上下文和该模板的专门化实例化点之间改变。其中包括初始化(影响对象是否可以在常量表达式中使用),函数和模板默认参数以及类型的完整性。关于在定义上下文中还是在实例化时检查这些内容,存在实现上的分歧。如果在两个上下文之间这种引用的有效性发生变化,则可能需要一个规则来使其格式错误,而无需诊断。
您能否向我展示更多有关两个上下文之间非依赖名称的特征有何不同的示例?通常约为8.2和8.3.1
这是一个例子:
extern const int b;
template<int, int>
void f(int);
template<int, const int &>
void f(long);
template<class>
void g() {
f<0, b>(0);
}
// #1
extern const int b = 0;
int main(){
g<int>();
}
// #2
在#1处的假设实例化将调用void f<0, b>(long)
,因为此时b
不是常量表达式,所以(int)
重载SFINAE消失了。#2处的实例化(这是的实例化点g<int>
)将调用void f<0, 0>(int)
,因为到那时b
是一个常量表达式,(int)
重载是可行的,并且可以赢得重载解决方案。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句