我需要创建一个std::tuple<const XYZ,...>
where XYZ is not copyable。这样的事情可能吗?我当前的代码
auto test() -> std::tuple<const XYZ> { return std::make_tuple(XYZ()); }
导致 Visual Studio 2010 中的 C2248 ......当我用 R 值构造元组时,我觉得这很可疑,所以我假设移动构造会开始......
我需要创建一个std::tuple<const XYZ,...>
where XYZ is not copyable。这样的事情可能吗?我当前的代码
auto test() -> std::tuple<const XYZ> { return std::make_tuple(XYZ()); }
导致 Visual Studio 2010 中的 C2248 ......当我用 R 值构造元组时,我觉得这很可疑,所以我假设移动构造会开始......
您的问题是该元素既不可复制,又不可复制const
。const XYZ
元素表现为成员const XYZ
;到 5.2.5p4 访问const XYZ
xvalue 上的元素将产生一个具有 union cv 资格的 xvalue,即具有有效类型const XYZ &&
。该类型不适合作为移动构造函数的参数,XYZ
因此将尝试调用已删除/私有复制构造函数。
另一种看待它的方式是,移动构造函数(例如 的移动构造函数std::tuple<...>
)必须确保其参数处于未指定但有效的状态。通过制作元素const
,您已经说过该元素的唯一有效状态是构造它的状态,因此移动构造函数不允许从它移动,即使它包含在 xvalue 中。
一种解决方法是定义一个const move构造函数const_cast
及其参数以委托给 move 构造函数:
XYZ(const XYZ &&xyz): XYZ(const_cast<XYZ &&>(xyz)) {}
有趣的是,使用 gcc-4.7.2 只需声明const move 构造函数就足够了;通过 RVO,可以省略对 const move 构造函数的实际调用。不要依赖这个。