Assume that there is a function which accepts several strings:
void fun (const std::initializer_list& strings) {
for(auto s : strings)
As for the second question, just do it this way:
template
void foo () {
fun({Args::value...});
}
The mechanism is pretty intuitive: you create an initalizer list that contains the expanded Args::value
pattern, thus resolving (in your case) to { A::value, B::value, C::value, D::value }
.
Here is a complete program:
#include
#include
void fun (const std::initializer_list& strings) {
for(auto s : strings)
{
std::cout << s << " ";
}
}
template
void foo () {
fun({Args::value...});
}
struct A { 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(); // where A, B, C, D are classes
}
And here is a live example.
As for the static assertion, you may write a type trait that determines whether a certain type has a member variable value
:
template
struct has_value : std::false_type { };
template
struct has_value().value), void>::value,
bool
>::type
> : std::true_type
{
typedef decltype(std::declval().value) type;
};
Then, you could use it this way:
template
struct check_has_value
{
static_assert(has_value::value, "!");
};
template
void foo () {
auto l = { (check_has_value(), 0)... };
fun({Args::value...});
}
Here is a live example of a successful check (all classes has a value
data member). Here is a live example of an unsuccessful check (class D
's data member is called values
)