具有const不可复制元素的元组

时间:2012-10-04 20:16:27

标签: c++ visual-c++ c++11 tuples visual-c++-2010

我需要创建一个std::tuple<const XYZ,...>,其中XYZ 不可复制。这样的事情甚至可能吗?我目前的代码

auto test() -> std::tuple<const XYZ> { return std::make_tuple(XYZ()); }

导致Visual Studio 2010中的C2248 ...当我用R值构造元组时,我发现这很可疑,所以我假设移动构造会启动......

1 个答案:

答案 0 :(得分:3)

您的问题是该元素既是不可复制的又是constconst 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移动构造函数的实际调用。不要依赖于此。