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):
- when inside
foo()
, check ifargs
containvalue
usingstatic_assert
- pass such values
fun()
forminitializer_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
Post a Comment