带有模板的C ++ 11非const constexpr函数:OK,没有模板:错误

时间:2013-10-01 21:51:38

标签: templates c++11

我使用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


提前谢谢

1 个答案:

答案 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
}