c++ - 来自元组的构造函数参数

标签 c++ struct constructor tuples

如果我有这样的结构:

struct Thing
{
  int x;
  int y;
  bool a;
  bool b;
}

然后我可以创建一个 Thing 对象,方法是:Thing t {1,2,true,false};。但是,如果我有一个元组,那么我会做类似的事情:

std::tuple<int, int, bool, bool> info = std::make_tuple(1,2,true,false);
Thing t { std::get<0>(info), std::get<1>(info).. // and so on

有更好的方法吗?

最佳答案

我们可以创建一个通用工厂函数,用于从类似元组的类型( std::tuplestd::pairstd::array 和结构化绑定(bind)世界中任意用户定义的类似元组的对象):

template <class T, class Tuple, size_t... Is>
T construct_from_tuple(Tuple&& tuple, std::index_sequence<Is...> ) {
    return T{std::get<Is>(std::forward<Tuple>(tuple))...};
}

template <class T, class Tuple>
T construct_from_tuple(Tuple&& tuple) {
    return construct_from_tuple<T>(std::forward<Tuple>(tuple),
        std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>{}
        );
}

在您的情况下将用作:

std::tuple<int, int, bool, bool> info = std::make_tuple(1,2,true,false);
Thing t = construct_from_tuple<Thing>(info); // or std::move(info)

这边,Thing仍然可以是一个聚合(不必添加构造函数/赋值),我们的解决方案解决了很多很多类型的问题。

作为一项改进,我们可以将 SFINAE 添加到两个重载中,以确保无法使用无效的元组类型调用它们。


等待接受分解将如何工作的措辞,对 std::get<Is> 的合格调用可能需要更改为对 get<Is> 的不合格调用它有特殊的查找规则。目前,这还没有实际意义,因为现在是 2016 年,我们还没有结构化绑定(bind)。


更新:在 C++17 中,有 std::make_from_tuple() .

关于c++ - 来自元组的构造函数参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38440844/

相关文章:

c++ - 为什么用()声明对象时不调用构造函数?

arrays - [首先,...休息] : A spread argument must either have a tuple type or be passed to a rest parameter. ts(2556)

c++ - 如何编写以负数结尾的循环 (MyProgrammingLab 11138)

c++ - Sqlite 作为 fopen() 的替代品?

c++ - 与共享库链接时 undefined reference

c - 指针调用的结构成员分配了不同的值

c - 使用指针和非指针变量释放结构体

c++ - 混淆堆内存和栈内存中的对象

c++ - 如何创建/设计数据结构?

java - 在 java 构造函数中传递 "this"