Selecting variable amount of vector elements in C++ Suppose we are given a C++ vector. We want to specify a variable amount of indices and select elements from a vector being indexed. I have two implementation: (A) one relies on C++11 initializer lists, and the second one (B) on va_list and  macro mess. Arrangement B is however funkier to type because it requires no typing the braces comprising the initializer list. 

So my main question is: which one should an adult C++ programmer use, if any?

coderodde.h:

#ifndef CODERODDE_H
#define CODERODDE_H

#include &lt;cstdarg&gt;
#include &lt;iostream&gt;
#include &lt;vector&gt;

#define NUM_ARGS(...) (sizeof((size_t[]){__VA_ARGS__}) / sizeof(size_t))

namespace coderodde {

    template&lt;class T&gt; 
    std::vector&lt;T&gt; select(const std::vector&lt;T&gt;&amp; vec, 
                          const std::vector&lt;size_t&gt;&amp; indices) 
    {
        std::vector&lt;T&gt; ret;

        for (auto index : indices) {
            ret.push_back(vec.at(index));
        }

        return ret;
    }

    template&lt;class T&gt;
    std::vector&lt;T&gt; select(const std::vector&lt;T&gt;&amp; vec, const size_t len, ...)
    {
        std::va_list ap;
        std::vector&lt;T&gt; ret;
        va_start(ap, len);

        for (size_t i = 0; i &lt; len; ++i) 
        {
            ret.push_back(vec.at(va_arg(ap, size_t)));
        }

        va_end(ap);
        return ret;
    }
}

#define SELECT(vec, ...) (select(vec, NUM_ARGS(__VA_ARGS__), __VA_ARGS__))

#endif // CODERODDE_H


The test driver main.cpp:

#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;vector&gt;
#include "coderodde.h"

using std::cout;
using std::endl;
using std::string;
using std::vector;
using coderodde::select;

void test_smart(const vector&lt;string&gt;&amp; input) 
{
    const size_t N = input.size();

    for (size_t ca = 0; ca &lt; N; ++ca) 
    {
        for (size_t cb = 0; cb &lt; N; ++cb) 
        {
            for (size_t cc = 0; cc &lt; N; ++cc) 
            {
                for (auto s : select(input, { ca, cb, cc }))
                {
                    cout &lt;&lt; s;
                }

                cout &lt;&lt; endl;
            }
        }
    }

}

void test_stupid(const vector&lt;string&gt;&amp; input) 
{
    const size_t N = input.size();

    for (size_t ca = 0; ca &lt; N; ++ca) 
    {
        for (size_t cb = 0; cb &lt; N; ++cb) 
        {
            for (size_t cc = 0; cc &lt; N; ++cc) 
            {
                for (auto s : SELECT(input, ca, cb, cc))
                {
                    cout &lt;&lt; s;
                }

                cout &lt;&lt; endl;
            }
        }
    }
}

int main(int argc, char** argv)
{
    std::vector&lt;std::string&gt; string_vec {"A", "B", "C", "D"};
    cout &lt;&lt; "Smart:" &lt;&lt; endl;
    test_smart(string_vec);
    cout &lt;&lt; "Stupid:" &lt;&lt; endl;
    test_stupid(string_vec);
    return 0;
}
You can avoid problems related to variadic macros and problems related to C-style variadic functions altogether by creating a function that takes an std::initializer_list directly:

template&lt;class T&gt;
std::vector&lt;T&gt; select(const std::vector&lt;T&gt;&amp; vec, std::initializer_list&lt;std::size_t&gt; indices)
{
    std::vector&lt;T&gt; ret;
    for (std::size_t ind: indices) 
    {
        ret.push_back(vec.at(ind));
    }
    return ret;
}


Moreover, it is the easiest to read of the three implementations.