Мне нужно создать std::tuple<const XYZ,...>
где XYZ не копируется. Возможно ли что-то подобное? Мой текущий код
auto test() -> std::tuple<const XYZ> { return std::make_tuple(XYZ()); }
приводит к C2248 в Visual Studio 2010 … Что я нахожу довольно сомнительным, так как я создаю кортеж с R-значением, поэтому я предполагаю, что конструкция move перешла бы …
Ваша проблема в том, что элемент не копируемый и const
, const XYZ
элемент ведет себя как const XYZ
член; по 5.2.5p4 доступ к const XYZ
элемент в xvalue даст xvalue с квалификацией union cv, то есть с эффективным типом const XYZ &&
, Этот тип не подходит в качестве аргумента для конструктора перемещения XYZ
поэтому вместо этого будет предпринята попытка вызова конструктора удаленных / личных копий.
Другой способ взглянуть на это состоит в том, что конструктор перемещения (например, конструктор перемещения std::tuple<...>
) обязан убедиться, что его аргумент не указан, но действительный государство. Делая элемент const
Вы сказали, что единственным допустимым состоянием для этого элемента является состояние, с которым он построен, поэтому конструктору перемещения не разрешено перемещаться из него, даже если он содержится в xvalue.
Обходной путь должен был бы определить постоянный ход конструктор и const_cast
его аргумент для делегирования конструктору перемещения:
XYZ(const XYZ &&xyz): XYZ(const_cast<XYZ &&>(xyz)) {}
Забавно, но с gcc-4.7.2 достаточно просто объявлять конструктор const move; с помощью RVO фактический вызов конструктора const move может быть исключен. Не надейся на это.
Других решений пока нет …