4

我使用 g++ 4.8.1。编译:
g++ -std=c++11 test23.cpp test24.cpp -oa


测试24.cpp:

int gi1=98;

测试23.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>();
}

编译没有错误。不应该是错误吗?
现在没有模板:


测试23.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


先感谢您

4

1 回答 1

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();
}

func由于 [dcl.constexpr]/5 ,函数本身使程序格式错误:

对于一个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
}
于 2013-10-01T22:20:33.633 回答