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"
std::piecewise_construct
в f
в TU 1 относится к объекту, отличному от объекта в f
в TU 2. Я подозреваю, что f
нарушает ODR.
N3290 (возможно, также ISO / IEC 14882: 2011) говорит, что следующий случай является исключением из ODR, в 3.2 / 5:
имя может ссылаться на const-объект с внутренней связью или без нее, если объект имеет одинаковый литеральный тип во всех определениях 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