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