How to save parameters from a variable of a member function of a template to a vector?

#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");
}

only works when passing two parameters:

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

If I pass any number of parameters except two, I get an error.

For example:

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

Error: Severity code Description Project file line Error C2661 'std :: vector> :: push_back': no ​​overloaded function accepts 2 Arguments

+4
source share
3 answers

Call a function recursively.

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...);


}
+6
source

Non-recursive method:

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;
};

The real material is:

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

(foo(), 0)the comma operator is used. This is the first part (the work we want) and evaluate how 0.

With a variational extension it becomes (m_stringsvec.push_back(args), 0)....

.

++ 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;
        }
    }
+3

Another non-recursive option (warning, brain compilation):

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;
};
+1
source

Source: https://habr.com/ru/post/1622048/


All Articles