代码之家  ›  专栏  ›  技术社区  ›  Przemek Kryger

C++完美前向复制类型到make_tuple

  •  3
  • Przemek Kryger  · 技术社区  · 8 年前

    我在玩这个小片段:

    #include <tuple>
    
    struct copy_only
    {
        copy_only() = default;
        copy_only(copy_only&&) = delete;
        copy_only(const copy_only&) = default;
    };
    
    template <typename ...Ts>
    void foo(Ts&& ...xs)
    {
        auto t = std::make_tuple(std::forward<Ts>(xs)...);
        (void) t;
    }
    
    int main()
    {
       foo(copy_only{});
    }
    

    它适用于仅移动类型。至少在Wandbox上提供的上述编译器上。

    这段代码是c++14中通用完美转发到元组的正确方法的示例吗?

    1 回复  |  直到 8 年前
        1
  •  2
  •   Community THelper    4 年前
        auto t = std::make_tuple(std::forward<Ts>(xs)...);
    

    这确实是将参数转发到元组的正确方法。

    您得到的编译错误是由显式声明 copy_only 的移动构造函数已删除。通常,如果你声明了一个复制构造函数,它会被省略,并且在移动上下文中会选择复制构造函数-从C++98开始就是这样。但由于你显式声明了它,它确实参与了重载解析,如果选择了它,会导致代码格式不正确。

    霍华德·希南特提供了一张有用的图表: chart

    这可以通过从类定义中删除违规行来解决:

    struct copy_only
    {
        copy_only() = default;
        //copy_only(copy_only&&) = delete;
        copy_only(const copy_only&) = default;
    };
    

    现在,关于您的代码是否应该编译:据我所知,应该是这样。 tuple 的移动构造函数定义为:

    tuple(tuple&& u) = default;

    要求 : is_move_constructible<Ti>::value 对所有人都是如此 .

    自从 仅复制 不可移动构造,不应声明它,也不应参与重载解析。