6

Suppose, I have a structure

struct A
{
   std::string name;
};

and want to write function which reads field "name" from objects and return them as std::vector<std::string>. Is it possible to do this by variadic templates (or any non-iterative method). My goal is something like this:

template<typename... Ts>
std::vector<std::string> function(Ts... ts)
{
    ...
}

in program:

    A a1, a2, a3, a4;
    function(a1, a2, a3, a4);

output: {a1.name, a2.name, a3.name, a4.name}

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
Piodo
  • 616
  • 4
  • 20

1 Answers1

12

A really simple expansion that works in C++11:

template <typename ... Ts>
std::vector<std::string> function(Ts&& ... ts)
{
    return {std::forward<Ts>(ts).name...};
}

(forwarding references not required)

What happens is, that the vector is constructed with initializer list, constructed from the variadic parameter pack, while applying a function (member access operator) for each variadic element.

LogicStuff
  • 19,397
  • 6
  • 54
  • 74
  • 1
    Does the perfect forwarding work here? In case of `function(std::move(a1));`, `a1` will be treated as rvalue, but it's `name` member variable will be an lvalue. Or, will not? – Daniel Langr Dec 17 '18 at 11:39
  • 3
    Sorry, just found out that the member variable will be rvalue as well (https://stackoverflow.com/a/8609226/580083). Didn't know this rule. – Daniel Langr Dec 17 '18 at 11:42
  • 1
    @DanielLangr To be honest, you made me doubtful, so thanks for the link. – LogicStuff Dec 17 '18 at 11:46