解压方法参数的元组

时间:2016-05-04 11:55:35

标签: c++ tuples c++14

我将元组扩展为其内容存在语法问题。

我的工作代码:

class Example
{
    public:
        static void Go( int i, float f)
        {
            std::cout << "p1: " << i << std::endl;
            std::cout << "p2: " << f << std::endl;
        }

        template <typename T, size_t ... I>
            static void Do( T parm )
        {
            Go( std::get<I>( parm)...);
        }
};

int main()
{
    using X = std::tuple<int, float>;
    Example::Do<X,0,1>( std::make_tuple( 1,2.2)) ;
}

但我想用类似

之类的东西来调用扩展
int main()
{
    using X = std::tuple<int, float>;
    using IDX = std::std::index_sequence_for<int, float>;
    Example::Do<X,IDX>( std::make_tuple( 1,2.2)) ;
}

所以我正在寻找像(不能编译......)的东西:

template <typename T, size_t ... I>
static void Do<T, std::index_sequence<I...>>(T parm)
   {
            Go( std::get<I>( parm)...);
   }

2 个答案:

答案 0 :(得分:1)

按值传递索引序列:

template <typename T, size_t... I>
static void Do(T parm, std::index_sequence<I...>)
{
    Go(std::get<I>(parm)...);
}

调用这样的方法:

Example::Do(std::make_tuple(1, 2.2), 
    std::index_sequence_for<int, float>{});

答案 1 :(得分:1)

问题是您的std::index_sequenceIDX)未在模板参数中扩展到您需要的内容:

Example::Do<X, IDX>(std::make_tuple(1, 2.2));

...不会&#34;扩展&#34;到:

Example::Do<X, 0, 1>(std::make_tuple(1, 2.2)); // This works

您需要让编译器推导出...I的模板参数,这样做会将静态方法更改为:

template <typename T, size_t ... I>
static void Do(T parm, std::index_sequence<I...>)
{
    Go(std::get<I>(parm)...);
}

然后用:

来调用它
Example::Do(std::make_tuple(1, 2.2), IDX{});

编译器将自动推导出模板参数,并根据需要调用Example::Do<X, 0, 1>

如果您希望能够在没有第二个参数的情况下调用Do,则可以在Example中添加另一个抽象层:

class Example
{
public:
    static void Go(int i, float f) {
        std::cout << "p1: " << i << std::endl;
        std::cout << "p2: " << f << std::endl;
    }

    template <typename Tuple>
    static void Do(Tuple &&parm) {
        _Do(std::forward<Tuple>(parm),
            std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>{}>{});
    }

private:

    template <typename Tuple, size_t... I>
    static void _Do(Tuple &&parm, std::index_sequence<I...>) {
        Go(std::get<I>(std::forward<Tuple>(parm))...);
    }
};

然后:

Example::Do(std::make_tuple(1, 2.2));

请注意三个版本:

Example::Do<X, 0, 1> (std::make_tuple(1, 2.2));
Example::Do(std::make_tuple(1, 2.2), IDX{});
Example::Do(std::make_tuple(1, 2.2));

在编译器优化后可能会产生相同的代码(在我的机器上clang++-3.7-O1,三个汇编文件严格相同)。