Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我可以从向量数组初始化std::tuple吗?_C++_Tuples_Stdtuple - Fatal编程技术网

C++ 我可以从向量数组初始化std::tuple吗?

C++ 我可以从向量数组初始化std::tuple吗?,c++,tuples,stdtuple,C++,Tuples,Stdtuple,我有一个包含变量类的std::vector。我想用相同的数据构造一个元组。这可能吗?元组的常规构造方法似乎有很大的限制 //In reality, I'm using JUCE::var. // SimpleVariant is here just to make the example code more explicit. struct SimpleVariant { SimpleVariant(int

我有一个包含变量类的std::vector。我想用相同的数据构造一个元组。这可能吗?元组的常规构造方法似乎有很大的限制

                    //In reality, I'm using JUCE::var.
                    // SimpleVariant is here just to make the example code more explicit.
struct SimpleVariant
{
    SimpleVariant(int i) :                a(i), b("") {}
    SimpleVariant(const std::string& s) : a(0), b(s) {}

    operator int() const { return a; }
    operator std::string() const { return b; }

private:
    int a;
    std::string b;
};


template <typename... T>
struct VariantTuple
{
    VariantTuple(const std::vector<SimpleVariant>& v)
    {
        // how do I initialize the tuple here?
    }

private:
    std::tuple<T...> tuple;
};


        std::vector<SimpleVariant> v{ SimpleVariant(1),
                                      SimpleVariant(2),
                                      SimpleVariant("a") };

        VariantTuple<int, int, std::string> t (v);
//实际上,我使用的是JUCE::var。
//SimpleVariant在这里只是为了使示例代码更加明确。
结构简单变量
{
简单变量(inti):a(i),b(“”{}
SimpleVariant(const std::string&s):a(0),b(s){
运算符int()常量{返回a;}
运算符std::string()常量{return b;}
私人:
INTA;
std::字符串b;
};
模板
结构变量偶
{
变量偶(常量标准::向量和v)
{
//在这里如何初始化元组?
}
私人:
std::tuple;
};
向量v{SimpleVariant(1),
简单变量(2),
简单变量(“a”)};
变量t(v);
一些基于评论的澄清:


我不需要元组逐项匹配数组项,也不需要从给定数组推断类型。我想获取给定的数组,然后提取与特定类型匹配的变体。因此,例如,给定上述数组
v
,我希望能够构造一个
VariantTuple
,并使其与术语“1”和“a”匹配。这引出了许多超出我最初问题范围的其他问题。但我现在感兴趣的问题是,是否有可能首先基于数组构造一个元组。

我不确定您是否要求动态推断向量元素的数量并构造元组,这是不可能的,但现在开始。我使用了
std::index_sequence
根据
VariantTuple
的参数大小推断元组元素的数量。这需要C++17,因为它使用折叠表达式

#include <initializer_list>
#include <string>
#include <vector>
#include <tuple>
#include <utility>
#include <type_traits>
#include <ostream>
#include <iostream>

struct SimpleVariant
{
    SimpleVariant(int i) :                a(i), b("") {}
    SimpleVariant(const std::string& s) : a(0), b(s) {}

    operator int() const {
        return a;
    }

    operator std::string() const {
        return b;
    }

    int a;
    std::string b;
};

template<typename V, size_t... dim, typename... Args>
auto populate_tuple(const V& vec, std::index_sequence<dim...>, const std::tuple<Args...>& t) {
    return std::make_tuple(static_cast<std::remove_reference_t<decltype(std::get<dim>(t))>>(vec.at(dim))...);
}

template<size_t... dim, typename... Args>
std::ostream& dump_tuple(std::ostream& out, const std::tuple<Args...>& tpl, std::index_sequence<dim...>) {
    ((out << std::get<dim>(tpl) << ","), ...);
    return out;
}

template<typename... T>
struct VariantTuple
{
    VariantTuple(const std::vector<SimpleVariant>& v) : tpl(populate_tuple(v, std::make_index_sequence<sizeof...(T)>{}, tpl)) {}

    template<typename... V>
    friend std::ostream& operator <<(std::ostream& out, const VariantTuple<V...>& vt) {
        return dump_tuple(out, vt.tpl, std::make_index_sequence<sizeof...(V)>{});
    }
private:
    std::tuple<T...> tpl;
};

int main() {
    std::vector<SimpleVariant> v { 
        SimpleVariant(1),
        SimpleVariant(2),
        SimpleVariant("a") 
    };
    VariantTuple<int, int, std::string> t (v);
    std::cout << t << std::endl;

    return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
结构简单变量
{
简单变量(inti):a(i),b(“”{}
SimpleVariant(const std::string&s):a(0),b(s){
运算符int()常量{
返回a;
}
运算符std::string()常量{
返回b;
}
INTA;
std::字符串b;
};
模板
自动填充\u元组(常量V和vec、std::index\u序列、常量std::元组和t){
返回std::make_tuple(static_cast(vec.at(dim))…);
}
模板
std::ostream和dump_tuple(std::ostream和out,const std::tuple和tpl,std::index_序列){

((问题标题提到数组,但问题测试和示例使用
vector
s。你在问什么?如果结果元组作为函数参数而不是直接返回值给出,这是可能的,但它需要编译所有可能的类型排列,这会很快在变量大小中爆发。)e和向量长度。@chris你需要设置向量大小的上限来编译可能生成的每个元组。这不是很实用。但是你可以用
std::array
来实现这一点。@FrançoisAndrieux,对,它适用于长度较低的情况,编译时间对较高的情况非常糟糕。你真的使用了吗ng
SimpleVariant
或者它只是一个例子?你可以用
std::variant
来代替吗?
SimpleVariant
看起来很难用作
variant
,这会使你想用它做的任何事情变得更加复杂。你已经构建了向量,不是吗?执行URL,我使用了用户-定义的转换运算符将
t
更改为
std::tuple&t
中的
populate\u tuple
为我修复了它。它正在执行一个未初始化的
tuple
的副本@FrançoisAndrieux,您需要通过引用传递该元组,我将编辑答案,gcc没有显示警告,clang显示了。这似乎很好,因为e更改为
t
。但是将未初始化的
tpl
作为参数传递给
populate\u tuple
是一种代码气味,在任何代码检查中都会引起关注。也许您可以通过传递
decltype(tpl)来传递tuple
改为模板参数,并使用
std::tuple\u element\u t
代替
decltype(std::get(t))>
。编辑:示例: