我使用g ++ 4.8.1。
编译:
g ++ -std = c ++ 11 test23.cpp test24.cpp -o a
test24.cpp:
int gi1=98;
test23.cpp:
extern int gi1; // compiler cannot predict the value
template<class T>
constexpr bool f8() {
return (gi1 > 5);
}
// constexpr bool ce = f8<float>(); // OK, it is compile error
int main() {
bool bz1 = f8<float>();
}
编译没有错误。不应该是错误吗? 现在没有模板:
test23.cpp:
extern int gi1;
constexpr bool f8() {
return gi1 > 5;
}
int main() {
bool bz1 = f8();
}
好的,编译错误: test23.cpp:4:1:错误:'gi1'的值在常量表达式中不可用 test23.cpp:1:12:注意:'int gi1'不是const
提前谢谢
答案 0 :(得分:2)
虽然它有助于理解,但演示此问题并不需要在另一个翻译单元中定义extern
变量。任何可能不会出现在常量表达式中的东西就足够了:
int i = 42;
// neither const nor constexpr
// lvalue-to-rvalue conversion of it may not appear in a constant expression
constexpr int j = i; // error
template<class T>
constexpr int func_templ() { return i; }
constexpr int func () { return i; } // error
int main() {
// constexpr int rest = func_templ<void>(); // OK, it is compile error
int result = func_templ<void>();
result = func();
}
由于[dcl.constexpr] / 5,函数func
本身使程序格式不正确:
对于
constexpr
函数,如果不存在函数参数值,使得函数调用替换将产生常量表达式(5.19),则程序格式错误;无需诊断。
仅包含常量表达式的constexpr
函数不。但在这种情况下,它总是产生非常量表达式。因此,该计划是不正确的。对于函数模板func_temp
,它也是同样的问题。但是,g ++和clang ++不会产生诊断消息。也许是因为名称查找对于模板来说更复杂,即使在这种情况下它是普通的非依赖查找。
为了演示错误,这里有一个编译好的版本:
int i = 42;
constexpr int func(bool p)
{ return p ? 42 : i; }
int main() {
constexpr int result0 = func(true); // works
//constexpr int result1 = func(false); // error
int result2 = func(false); // works
}