4

我需要创建一个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 值构造元组时,我觉得这很可疑,所以我假设移动构造会开始......

4

1 回答 1

3

您的问题是该元素既不可复制,又不可复制constconst XYZ元素表现为成员const XYZ;到 5.2.5p4 访问const XYZxvalue 上的元素将产生一个具有 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 构造函数的实际调用。不要依赖这个。

于 2012-10-05T18:18:52.600 回答