c++ - 初始化不可复制和不可移动类的元组

标签 c++ stdtuple

考虑具有唯一自定义构造函数的类 A:

class A
{
public:
    A(float) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

还有另一个类 B,它包含 A 的一个元组(为简单起见,让它成为唯一的元组成员):

class B
{
public:
    B() : ta(0.0f) {} // ta initialization OK

private:
    std::tuple<A> ta;
};

现在我们可以声明 B 的一个对象,它工作正常:

B b;

但是如果 A 的构造函数有多个参数,如何做同样的事情呢?

class A
{
public:
    A(float, int) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

class B
{
public:
//  B() : ta(0.0f, 1) {} // Compilation errors
//  B() : ta({0.0f, 1}) {} // Compilation errors
//  B() : ta{0.0f, 1} {} // Compilation errors
//  B() : ta(A(0.0f, 1)) {} // No constructor to copy or move A

private:
    std::tuple<A> ta;
};

B b;

std::make_tuplestd::forward_as_tuple 和其他类似的东西没有解决问题,因为 A< 的默认、复制和移动构造函数 被禁用。

最佳答案

std::tuple 几乎没有就地构造其成员的工具。初始化 tuple 的普遍预期方式是通过从其组件对象复制/移动。

它确实允许将构造函数参数隐式转换为其各自的实参。但这只是参数和 tuple 成员之间的 1:1 关系。构造函数参数和 tuple 成员之间无法建立多对一关系。

可以允许您的类型可以从tuple 本身隐式构造:

class A
{
public:
    A(float, int) {}
    A(const std::tuple<float, int> &tpl)
        : A(std::get<0>(tpl), std::get<1>(tpl)) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;
};

因此,您可以像这样构造一个元组:

class B
{
public:
    B() : ta(std::tuple<float, int>(0.0f, 1)) {}

private:
    std::tuple<A> ta;
};

如果你想使用更深层次的元编程,你可能还能够制作一组构造函数,允许你的类型从一个 tuple 构造,其类型匹配任何可用的构造函数:

class A
{
public:
    A(float, int) {}

    template<typename ...Args>
    A(const std::tuple<Args...> &args) : A(args, std::index_sequence_for<Args...>{}) {}

private:
    A() = delete;
    A(const A&) = delete;
    A(A&&) = delete;

    template<typename ...Args, std::size_t ...Is>
    A(const std::tuple<Args...> &args, std::index_sequence<Is...>) 
        : A(std::get<Is>(args)...) {}
};

关于c++ - 初始化不可复制和不可移动类的元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41657356/

相关文章:

c++ - DLL 注入(inject)在目标进程中不起作用

c++ - 为什么在 C++ 中不为私有(private)嵌套类调用析构函数?

c++ - 如何从参数包构造引用的 std::tuple?

c++ - 为什么我不能在constexpr lambda函数中使用std::tuple

c++ - 关闭任何句柄后,CreateFile FILE_FLAG_DELETE_ON_CLOSE 失败

c++ - 微软的 CopyFileEx 错误

c++ - 创建一个包含不同驱动类元素的元组,其构造函数接收一个 int 类型,由其在元组中的索引确定

C++ 多次转发一个引用 : first copy and then move

c++ - 如何对 std::tuple 中的每个元素应用 constexpr 函数?

c++ - CGAL:修改从定位调用中获取的扩展 DCEL