我需要创建一个std::tuple<const XYZ,...>
,其中XYZ 不可复制。这样的事情甚至可能吗?我目前的代码
auto test() -> std::tuple<const XYZ> { return std::make_tuple(XYZ()); }
导致Visual Studio 2010中的C2248 ...当我用R值构造元组时,我发现这很可疑,所以我假设移动构造会启动......
答案 0 :(得分:3)
您的问题是该元素既是不可复制的又是const
。 const XYZ
元素表现为const XYZ
成员;通过5.2.5p4访问xvalue上的const XYZ
元素将产生具有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移动构造函数;通过RVO,可以省略对const移动构造函数的实际调用。不要依赖于此。