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)
};
}
翻訳単位 1
#include "a.hpp"
翻訳単位 2
#include "a.hpp"
TU 1のstd::piecewise_construct
inは、TU 2のf
in とは異なるオブジェクトを参照しています。ODR に違反していると思われます。f
f
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 &
とても困惑しています。
参照: http://lists.boost.org/Archives/boost/2007/06/123353.php