我想通过使用模板元编程从变量 args 中剥离参数

I want strip argument from variable args by using template meta programming

我是模板元编程的新手。我想从 C++ 中的变量参数中剥离 args 。我正在制作一个函数,它将 push_back() 元素添加到任何类型的容器中。在 C++ 17 中很容易做到,但我想为 C++ 11 提供支持。请在下面找到我正在寻找的 push_back() 函数实现的代码。请避免 va_start()va_end() c 风格的解决方案。


#include <iostream>
#include <vector>
template<class Container, class T, class... Args>
void push_back(Container& con, T tail, Args... args);

template<class T>
T get_tail(T data) {
    return data;
}

template<class T, class ...Args>
T get_tail(T& tail, Args&... args) {
    return tail;
}

template<class Container , class T,class... Args>
void push_back(Container& con, T tail,Args... args ) {
        //C++ 17 ((con.push_back(args), ...);
    con.push_back(tail);
    std::cout << (tail) << std::endl;
    T newTail = get_tail(args...);
    push_back(con,newTail,args...); 
}

template<typename T, typename... Args>
bool pair_comparer(T a, T b, Args... args) {
    return a == b && pair_comparer(args...);
}

int main()
{
    std::vector<int> v_int;
    push_back(v_int,1,2,3,4 );
  std::cout << "Hello World!\n";
    for (auto iter = v_int.begin(); iter != v_int.begin(); iter++) {
        std::cout << "=== " << *iter << " ===" << std::endl;
    }
}

你已经删除了第一个参数

void push_back(Container& con, T tail, Args... args ) {

tail 是第一个参数,args 是其余参数,所以最后的递归调用只需要说

pus_back(con, args...)

不需要任何这种 get_tail 骇客。然后,简单地重载 push_back,如下所示。

template <class Container>
void push_back(Container& con) {
  // A whole lot of nothing happens here...
}

处理基本情况,而您已经编写的函数(稍作修改)处理递归情况。

您的代码中的问题是您使用 相同的 个参数在自身内部调用 push_back。这使得递归无限。相反,您每次都需要 "strip" 一个参数。并且当然提供递归基础。像这样:

template<class Container>
void push_back(Container& con) {
}

template<class Container , class T,class... Args>
void push_back(Container& con, T tail, Args... args ) {
    con.push_back(tail);
    std::cout << (tail) << std::endl;
    push_back(con, args...);
}


int main()
{
    std::vector<int> v_int;
    push_back(v_int,1,2,3,4 );
    std::cout << "Hello World!\n";
    for (auto x : v_int)
        std::cout << "=== " << x << " ===" << std::endl;
}

不确定您到底想要什么但是...

你确定你需要递归吗?

您可以使用未使用的 C-style 数组的初始化来开发类似于 C++17 解压可变参数 args... 的方法,如下所示

template <typename Container, typename ... Args>
void push_back (Container & con, Args ... args ) {
   using unused = int[];

   (void)unused { 0, ((void)con.push_back(args), std::cout << args << std::endl, 0)... };
}

或者简单如下

template <typename Container, typename ... Args>
void push_back (Container & con, Args ... args ) {
   using unused = int[];

   (void)unused { 0, ((void)con.push_back(args), 0)... };
}

如果 std::cout 部分仅用于调试目的。