如何在C++中用给定的伪代码创建一个递归的variadic函数?

问题描述 投票:0回答:1

我正试图制作一个递归的变量模板函数,它可以在下面的例子中工作。这个例子没有显示出任何实用性,只是用来帮助更好地理解我的要求。所以,基本上我有一个函数,它接受无限量的相同类型的参数,除了最后一个参数之外,它递归调用自己。然后,一旦它最终达到两个参数,下一个unction作为函数的终止。我知道这个答案并不简单,我不知道到底该怎么做。任何帮助或方向都将被感激! 谢谢。

template <typename... Ts>
void test(int& a, int& b, Ts&... ts){
    test(a, b, ... ); //all but the last parameter

    //last parameter argument is processed here

}

void test(int& a, int& b){
    //end of recursion
}

int main(int argc, char** argv){

    int a = 3;
    int b = 5;
    int c = 6;
    int d = 4;

    test(a, b, c, d);

    return 0;
}
c++ templates recursion variadic-templates variadic
1个回答
0
投票

我们可以将参数转发到元组中,并将索引递减。

#include <cstddef>
#include <tuple>
#include <utility>

template <std::size_t I, typename Tuple>
void test_helper(Tuple&& tuple)
{
    if constexpr (I != 0) {
        test_helper<I - 1>(std::forward<Tuple>(tuple));
    }

    // for example
    process(std::get<I>(std::forward<Tuple>(tuple)));
}

template <typename... Args>
void test(Args&&... args)
{
    test_helper<sizeof...(Args) - 1>(std::forward_as_tuple(std::forward<Args>(args)...));
}

例子:

#include <cstddef>
#include <iostream>
#include <tuple>
#include <utility>

template <typename T>
void process(const T& arg)
{
    std::cout << arg << '\n';
}

template <std::size_t I, typename Tuple>
void test_helper(Tuple&& tuple)
{
    process(std::get<I>(std::forward<Tuple>(tuple)));

    if constexpr (I != 0) {
        test_helper<I - 1>(std::forward<Tuple>(tuple));
    }
}

template <typename... Args>
void test(Args&&... args)
{
    test_helper<sizeof...(Args) - 1>(std::forward_as_tuple(std::forward<Args>(args)...));
}

int main()
{
    test(1, '2', "3", 4.0);
}

(现场演示)


目前,更喜欢从左到右处理参数,这样更简单。

template <typename... Args>
void test(Args&&... args)
{
    ((void)process(std::forward<Args>(args)), ...);
}

处理从右到左的参数会变得更简单 P1858 通用包件申报和使用,可惜还没有被采用。

template <typename... Args>
void test(Args&&... args)
{
    test(std::forward<Args>(args)...[:-1]...);

    if constexpr (sizeof...(Args) != 0) {
        process(std::forward<Args>(args)...[-1]);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.