为什么单一定义规则使用(odr-use)取决于上下文?

时间:2016-06-17 10:16:28

标签: c++ c++11 constexpr one-definition-rule

给出以下代码:

#include <iostream>

struct A {
    static constexpr float a = 2.0f;
};

// non-const reference to make it more explicit - same behaviour
template<class T> constexpr inline T square(T& x)
{
    return x * x;
}

int main() {
    /*constexpr*/ float val = square(A::a);
    std::cout << val;
}

此程序无法与undefined reference to 'A::a'(始终使用clang,仅使用-O0和g ++)链接,但如果我从constexpr声明中取消注释val,则链接正确。< / p>

到目前为止,我理解constexpr如果没有在其中一个单元文件中进行明确定义,就无法使用constexpr,但我不明白为什么在分配给map.getStyle().layers时它会起作用。

根据上下文,似乎这两种情况的处理方式不同。但为什么?在这两种情况下,编译器是否应该只在编译时评估此函数?

1 个答案:

答案 0 :(得分:4)

  

为什么odr-use取决于上下文?

没有。 square(A::a) odr-uses A::a,句号。

但是,大多数ODR违规都不需要诊断,这也不例外。

  

在这两种情况下,编译器是否应该只在编译时评估此函数?

必须在编译时评估constexpr变量的初始值设定项。 (嗯,不完全,但是编译器必须将它评估到可以确定它是一个有效的常量表达式的点,此时它也可以完成整个事情。)对于非{{1}局部变量,没有这样的保证。