4

当您深入了解细节时,标准中的 odr-used 定义非常令人困惑(至少对我来说是这样)。我通常依赖“如果引用”的非正式定义,除非可以进行左值到右值的转换。对于整数常量,它们应该被视为右值,这似乎应该从引用规则中排除。这是我无法链接的示例代码:

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

我得到的链接器错误:

clang++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
/tmp/main-e2122e.o:在函数“Test::Test()”中:
main.cpp:(.text+0x2): 未定义对“Test::MIN_VALUE”的引用
clang:错误:链接器命令失败,退出代码为 1(使用 -v 查看调用)

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

为什么定义是MIN_VALUE必需的?它只是文字值的常量,编译器应将其优化为std::max(m_otherValue, 5). 所以我就是不明白。

4

2 回答 2

7

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

于 2015-07-17T22:46:42.773 回答
1

如果您阅读参考资料,std::max您会发现它通过参考资料获取参数,并根据此 odr-used 参考资料

非正式地,一个对象是 odr-used 如果......一个引用被绑定到它......

由于您传递MIN_VALUE给一个接受引用的函数,因此该成员是odr-used并且需要单独的定义。

于 2015-07-17T22:48:36.977 回答