#include <initializer_list>
#include <iostream>
#include <string>
#include <type_traits>

using namespace std;

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

template <typename T>
struct HasValue
{
    typedef char OK;
    struct BAD { char x[2]; };
    template <const string *>
    struct Helper;
    template <typename X>
    static OK has(X*, Helper<&X::value>* = nullptr);
    static BAD has(...);
    
    static const bool value = (sizeof(has((T*)nullptr)) == sizeof(OK));
};

template <typename H, typename... T>
struct HaveValue : public integral_constant<bool, HasValue<H>::value && HaveValue<T...>::value>
{};

template <typename H>
struct HaveValue<H> : public HasValue<H>
{};



template <typename... Args>
void foo() {
    static_assert(HaveValue<Args...>::value, "All arguments must have const string ::value");
    fun({Args::value...});
}

struct A
{
    static const string value;
};
const string A::value = "AA";

struct B
{
    static const string value;
};
const string B::value = "BB";

struct C{};

int main()
{
    foo<A, B>();
    //foo<A, B, C>();
}