Reputation: 10911
I want to have a template parameter accept a template that has a numeric template argument.
This example maybe overly simplified, but I'd like something like this:
template <int X>
struct XX
{
static const int x = X;
};
template<typename TT, TT V, template<V> TX>
void fnx(TX<V> x)
{
static_assert(V == TX::x, "IMPOSSIBLE!");
}
void fny()
{
fnx(XX<1>())
}
I must not be understanding the syntax for this, as it must be possible. How would I accomplish this?
Upvotes: 6
Views: 213
Reputation: 303127
Just fixing up your syntax a bit - since the template template parameter is improperly specified, we'd end up with something like this:
template <typename T, template <T > class Z, T Value>
// ^^^^^^^^^^^^^^^^^^^^^
void foo(Z<Value> x) { }
However, the compiler can't deduce T
here - it's a non-deduced context. You'd have to explicitly provide it:
foo<int>(XX<1>{});
That's pretty annoying. I cannot even write a type trait such that non_type_t<XX<1>>
is int
(where that type trait does actual introspection on the type, not something that trivially returns int
).
There is a proposal to improve this process (P0127) by amending the non-deduced context-ness of non-type template arguments.
Upvotes: 6
Reputation: 18964
Your declaration of fnx
needs some work, and the type TT
can't be deduced at the call site.
template<typename TT, TT V, template<TT> class TX>
void fnx(TX<V> x)
{
static_assert(V == TX<V>::x, "IMPOSSIBLE!");
}
void fny()
{
fnx<int>(XX<1>());
}
Working example: https://ideone.com/57PsCA
Upvotes: 2