Let's say I have:
template <typename...>
class Foo { };
Then I define another function:
template <typename... T>
void Bar(const T&... arguments) { }
How do I check if all T
s passed to Bar
are all instantiated from Foo
? Like:
Foo<int> a;
Foo<int, int> b;
Bar(a, b); // OK
int c;
Bar(a, b, c); // ill-formed
I want a way to detect ill-formed arguments like Bar(a, b, c);
Is there a way to do this?
You can create a trait to test for instantiations of Foo
, and then fold it across all your parameters.
template <typename>
struct is_foo : std::false_type {};
template <typename... Ts>
struct is_foo<Foo<Ts...>> : std::true_type {};
template <typename T>
constexpr bool is_foo_v = is_foo<T>::value;
template <typename... T>
void Bar(const T&... arguments) {
static_assert((is_foo_v<T> && ...), "arguments must all be Foos");
}