考虑以下代码:
class Test {
public:
static const int VALUE = 100;
};
std::tuple<int> foo(std::tuple<int> value) {
return value;
}
int main()
{
auto t = std::make_tuple(Test::VALUE); // This compiles fine
auto t1 = foo(std::make_tuple(Test::VALUE)); // undefined reference to `Test::VALUE' linker error
}
根据另一个问题(“ODR 使用”某物是什么意思?)和答案:
简单来说,odr-used 意味着某些东西(变量或函数)在必须存在其定义的上下文中使用。
在第一种情况下(变量t
) 变量VALUE
不使用 odr,因为只需要它的值。但在第二种情况下,为什么代码无法编译呢?如果我能通过t
而不是传递右值(?),代码可以正常编译。第二种情况与第一种情况有何不同以及原因VALUE
这里使用的是odr吗?
make_tuple
采用论证const int&
(因为它是一个常量左值并且需要T&&
参数),并且将引用绑定到值是 ODR 使用。
这两种情况都是病态的,不需要诊断。例如,在 gcc 的高优化级别下,整个程序都经过优化,并且没有链接器错误,而在没有优化的情况下,两个语句都会给出链接器错误。
为了使其不被 ODR 使用,您可以将其转换为右值:
// Various ways to force the lvalue-to-rvalue conversion
auto t = std::make_tuple(int(Test::VALUE));
auto t1 = foo(std::make_tuple((void(), Test::VALUE)));
auto t2 = foo(std::make_tuple(+Test::VALUE));
(So std::make_tuple
需要一个int&&
临时的)
或者你可以定义inline
(最简单的constexpr
):
class Test {
public:
static constexpr int VALUE = 100;
};
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)