当你进入细节时,标准中使用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;
}
我得到的链接器错误:
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)
。所以我只是不明白。
答案 0 :(得分:7)
std::max
通过引用而非值来获取其参数。不允许执行左值到右值转换,然后从该右值构造临时对象。 std::max
可以检查两个参数是否是对同一个对象的引用,对于所有编译器都知道,如果调用{true
,则需要进行检查std::max(MIN_VALUE, MIN_VALUE)
{1}}。
答案 1 :(得分:1)
如果您阅读了std::max
的参考文献,您会看到它通过参考进行参数,并根据this odr-used reference
非正式地说,如果......引用被绑定,那么对象就会被使用...
由于您将MIN_VALUE
传递给了一个带引用的函数,因此该成员 odr-used 并需要一个单独的定义。