如何将参数从可变参数模板成员函数存储到向量中

How to store parameters from variadic template member function into vector?

本文关键字:参数 函数 成员 存储 向量 变参      更新时间:2023-10-16
#include <Windows.h>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class CTest
{
public:
    template<typename... Args>
    void AddStringsToVector(const std::string &First, Args&... args);
private:
    std::vector<std::string> m_stringsvec;
};
template<typename... Args>
void CTest::AddStringsToVector(const std::string &First, Args&... args)
{
    m_stringsvec.push_back(First);
    m_stringsvec.push_back(args...);
    for (auto &i : m_stringsvec)
        std::cout << i << std::endl;
}
void main()
{
    CTest test;
    test.AddStringsToVector("test1","test2","test3");
    system("pause");
}

仅当我传递两个参数时才有效:

test.AddStringsToVector("test1","test2");

如果我传递除两个参数以外的任意数量的参数,则会出现错误。

例如:

test.AddStringsToVector("test1","test2","test3");

错误: 严重性代码描述项目文件行 错误 C2661 'std::vector>::p ush_back': 无重载函数需要 2 参数

递归调用函数。

void CTest::AddStringsToVector()//function to break recursion 
{
}
template<typename... Args>
void CTest::AddStringsToVector(const std::string &First, Args&... args)
{
    m_stringsvec.push_back(First);
    AddStringsToVector(args...);

}

一种非递归方法:

class CTest
{
public:
    template<typename... Args>
    void AddStringsToVector(const std::string &first, const Args&... args)
    {
        m_stringsvec.push_back(First);
        int dummy[] = { 0, (m_stringsvec.push_back(args), 0)...}; // all magic is here
        (void) dummy; // Avoid unused variable warning.
        for (const auto &s : m_stringsvec) {
            std::cout << i << std::endl;
        }
    }
private:
    std::vector<std::string> m_stringsvec;
};

真正的东西在那里:

int dummy[] = { 0, (m_stringsvec.push_back(args), 0)...};

(foo(), 0)使用逗号运算符。完成第一部分(我们想要的工作(并评估为0 .

随着可变参数展开,它变得(m_stringsvec.push_back(args), 0)....

将整个初始化项列表放入保证顺序评估中。

在 C++17 中,折叠表达式会更简单:

    template<typename... Args>
    void AddStringsToVector(const std::string &first, const Args&... args)
    {
        m_stringsvec.push_back(First);
         (m_stringsvec.push_back(args), ...); // Folding expression
        for (const auto &s : m_stringsvec) {
            std::cout << i << std::endl;
        }
    }

另一个非递归选项(警告,大脑编译(:

struct swallow { template <typename ...T> swallow(T&& ...) noexcept { } };
class CTest
{
public:
    template<typename... Args>
    void AddStringsToVector(const std::string &first, const Args&... args)
    {
        m_stringsvec.push_back(First);
        swallow{(m_stringsvec.push_back(args), 0)...};
        for (const auto &s : m_stringsvec) {
            std::cout << i << std::endl;
        }
    }
private:
    std::vector<std::string> m_stringsvec;
};