如何使用已知的非默认构造函数实例化未知大小的可变元组?

时间:2015-06-16 11:26:00

标签: c++

假设我有std::tuple种类型。我不知道它包含多少或哪些类型,但我知道每个元素都有一个构造函数只接受一个参数。

为了这个问题,让我们说参数是整数5但是直到运行时才知道该值

我如何构建这样的元组?

这是我到目前为止的尝试,它尝试使用编译时常量构造元组(我想要的,但它是一个起点):

#include <tuple>                                                                 

struct Fixture                                                                   
{

    // I don't know the value until runtime, so this is a poor
    // example anyway.
    template <typename T>                                                        
    struct Unpack                                                                
    {                                                                            
        static const int value = 5;                                    
    };                                                                           

    template <typename... T>                                                     
    struct Y                                                                     
    {                                                                            
        Y()                                                                      
        :   
            // this needs to be a runtime value                                                                     
            tup(Unpack<T>::value...)                                             
        {                                                                        
        }                                                                        

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

    Y<int, double, unsigned /*, some other classes */> y;                                                          
};                                                                               

除了丑陋(不应该Unpack类)并且只使用编译时已知的常量值时,这也会导致链接器错误:

  

架构x86_64的未定义符号:
  &#34; Fixture :: Unpack :: value&#34;,引自:         testTest.cpp.o中的Fixture :: Y :: Y()ld:找不到架构x86_64 clang的符号:错误:链接器命令失败   退出代码1(使用-v查看调用)

标准库或Boost中是否有一些元编程魔法可以使这项工作,最好是更简洁的语法?我觉得std::integer_sequence的某些内容可能对我有帮助,但我无法弄清楚如何!

2 个答案:

答案 0 :(得分:1)

诀窍是构造一个引用可变参数包的表达式,但其值是您的参数。在扩展时,它将成为您的参数的重复。逗号运算符做得非常好:

template <typename... T>
struct Y
{
    Y(int value)
    : tup((void(sizeof(T)), value)...)
    { }

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

转换为void是为了明确地丢弃逗号左侧的值。 sizeof(T)可以替换为引用T的任何内容。

答案 1 :(得分:0)

删除值的const,你可以使用这个

template<typename T>
T Fixture::Unpack<T>::value{};

定义每个可能的&#34;解压缩类型&#34;。

然后你可以在运行时使用类似的东西来更新值:

int main() {
    std::cin >> Fixture::Unpack<int>::value >> Fixture::Unpack<double>::value;
    Fixture f;
    std::cout << std::get<0>(f.y.tup) << " " << std::get<1>(f.y.tup);
}

Live Example