std::piecewise_construct
,在 <utility> 中定义,自声明以来具有内部链接constexpr
。我想知道std::piecewise_construct
在标头中使用是否会违反 ODR。例如:
一个.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 中的std::piecewise_construct
inf
指的是与f
TU 2 中不同的对象。我怀疑f
违反了 ODR。
N3290(也可能是 ISO/IEC 14882:2011)在 3.2/5 中表示以下情况是 ODR 的一个例外:
如果对象在 D 的所有定义中具有相同的文字类型,并且该对象使用常量表达式(5.19)初始化,并且值(但不是地址),则名称可以引用具有内部链接或没有链接的 const 对象该对象被使用,并且该对象在 D 的所有定义中具有相同的值;
f
满足几乎所有要求,但“使用对象的值(但不是地址)”对我来说似乎模棱两可。确实std::piecewise_construct_t
没有状态,但是调用 的分段构造函数std::pair
涉及调用 的隐式声明的复制构造函数std::piecewise_construct_t
,其参数是const std::piecewise_construct_t &
。地址被“使用”了,不是吗?
我很困惑。
参考: http: //lists.boost.org/Archives/boost/2007/06/123353.php