【发布时间】:2011-11-29 20:52:25
【问题描述】:
std::piecewise_construct,在 constexpr。我想知道在标头中使用 std::piecewise_construct 是否会违反 ODR。例如:
a.hpp
#include <utility>
#include <tuple>
struct point
{
point(int x, int y)
: x(x), y(y)
{}
int x, y;
};
inline std::pair<point, point> f(int x1, int y1, int x2, int y2)
{
return {
std::piecewise_construct,
std::forward_as_tuple(x1, y1), std::forward_as_tuple(x2, y2)
};
}
翻译单元 1
#include "a.hpp"
翻译单元 2
#include "a.hpp"
TU 1 中f 中的std::piecewise_construct 与TU 2 中f 中的对象不同。我怀疑f 违反了ODR。
N3290(也可能是 ISO/IEC 14882:2011)在 3.2/5 中表示以下情况是 ODR 的例外:
如果对象在 D 的所有定义中具有相同的文字类型,并且该对象使用常量表达式(5.19)初始化,并且值(但不是使用对象的地址),并且该对象在D的所有定义中具有相同的值;
f 几乎满足所有要求,但是“使用对象的值(但不是地址)”对我来说似乎模棱两可。 std::piecewise_construct_t 确实没有状态,但调用std::pair 的分段构造函数涉及调用std::piecewise_construct_t 的隐式声明的复制构造函数,其参数为const std::piecewise_construct_t &。地址被“使用”了,不是吗?
我很困惑。
【问题讨论】:
-
+1(我认为)对于 2 分钟后仍然让我毫无头绪的问题
-
这不是和
std::cout一样的问题吗? -
@Kerrek
std::cout未定义多次。它只是在其各自的标题中声明。 -
std::cout是extern并定义一次。 -
地址是否真的被使用了?注 84 表明它可能不会,因为
piecewise_construct_t的复制 ctor 是微不足道的,因此constexpr(7.1.5/4)
标签: c++ c++11 constexpr linkage one-definition-rule