c++ - Converting Variadic template pack into std::initializer_list -


assume there function accepts several strings:

void fun (const std::initializer_list<std::string>& strings) {   for(auto s : strings)     // } 

now, have variadic template function foo() as:

template<typename ...args> void foo () {   fun(???); } 

this method called externally as:

foo<a, b, c, d>(); // a, b, c, d classes 

and these classes passed arguments expected contain common static const member:

static const std::string value = "..."; 

here questions (how to):

  1. when inside foo(), check if args contain value using static_assert
  2. pass such values fun() form initializer_list; e.g. fun({a::value, b::value, ...});

searched several threads related variadic templates , unpacking still novice in area. explanation in little more detail appreciated.

as second question, way:

template<typename ...args> void foo () {   fun({args::value...}); } 

the mechanism pretty intuitive: create initalizer list contains expanded args::value pattern, resolving (in case) { a::value, b::value, c::value, d::value }.

here complete program:

#include <string> #include <iostream>  void fun (const std::initializer_list<std::string>& strings) {     for(auto s : strings)     {         std::cout << s << " ";     } }  template<typename ...args> void foo () {   fun({args::value...}); }  struct { static std::string value; }; struct b { static std::string value; }; struct c { static std::string value; }; struct d { static std::string value; };  std::string a::value = "hello"; std::string b::value = "world"; std::string c::value = "of"; std::string d::value = "variadic templates";  int main() {     foo<a, b, c, d>(); // a, b, c, d classes } 

and here live example.

as static assertion, may write type trait determines whether type has member variable value:

template<typename t, typename v = bool> struct has_value : std::false_type { };  template<typename t> struct has_value<t,     typename std::enable_if<         !std::is_same<decltype(std::declval<t>().value), void>::value,         bool         >::type     > : std::true_type {     typedef decltype(std::declval<t>().value) type; }; 

then, use way:

template<typename t> struct check_has_value {     static_assert(has_value<t>::value, "!"); };  template<typename ...args> void foo () {     auto l = { (check_has_value<args>(), 0)... };     fun({args::value...}); } 

here live example of successful check (all classes has value data member). here live example of unsuccessful check (class d's data member called values)


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -