std :: piecewise_construct不会导致ODR违规吗?

ior*_*ate 24 c++ one-definition-rule linkage constexpr c++11

std::piecewise_construct在<utility>中定义,因为它已声明,因此具有内部链接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)
    };
}
Run Code Online (Sandbox Code Playgroud)

翻译单位1

#include "a.hpp"
Run Code Online (Sandbox Code Playgroud)

翻译单位2

#include "a.hpp"
Run Code Online (Sandbox Code Playgroud)

TU 1中的std::piecewise_constructin表示f与TU 2中的对象不同f.我怀疑f违反了ODR.

N3290(也可能是ISO/IEC 14882:2011)表示以下情况是ODR的例外,在3.2/5中:

如果对象在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

Joh*_*itb 6

您似乎已经在该邮件列表发布中获得了答案.是的,在我看来,它是未定义的行为或至少没有足够清晰的定义行为.

有关正在讨论的相同问题,请参阅此usenet讨论.