链接器错误与静态常量似乎没有使用odr

voi*_*ter 4 c++ one-definition-rule c++14

当你进入细节时(至少对我而言),odr-used标准中的定义非常混乱.我通常依赖于"如果引用"的非正式定义,除非可以使用左值到右值转换.对于积分常数,它们应被视为rvalues,这似乎应该从参考规则中排除.这是我的示例代码无法链接:

class Test
{
public:
    Test();
    static constexpr int MIN_VALUE { 5 };
    int m_otherValue = 10;
};

Test::Test()
{
    m_otherValue = std::max(m_otherValue, MIN_VALUE);
}

int main()
{
    Test t;
}
Run Code Online (Sandbox Code Playgroud)

我得到的链接器错误:

clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
/tmp/main-e2122e.o: In function `Test::Test()':
main.cpp:(.text+0x2): undefined reference to `Test::MIN_VALUE'
clang: error: linker command failed with exit code 1 (use -v to see invocation)

现场样本:http://coliru.stacked-crooked.com/a/4d4c27d6b7683fe8

为什么MIN_VALUE要求的定义?它只是一个字面值的常量,编译器应该优化它std::max(m_otherValue, 5).所以我只是不明白.

小智 7

std::max通过引用而不是通过值来获取其参数.不允许执行左值到右值转换,然后从该右值构造临时对象.std::max 可能正在检查两个参数是否是对同一个对象的引用,对于所有编译器都知道,并且需要进行检查以进行评估,true就像调用它一样std::max(MIN_VALUE, MIN_VALUE).