Look at this example:
template <typename A>
struct Foo1 {};
template <typename A, typename B>
struct Foo2 {};
struct Bar1 {
template <typename A>
using Foo = Foo1<A>;
};
struct Bar2 {
template <typename A, typename B>
using Foo = Foo2<A, B>;
};
template <typename BAR>
struct Something {
template <typename ...P>
void func(typename BAR::template Foo<P...> foo) {
}
};
I'd like to achieve: if Something is specialized with Bar1, then I'd like to have a template function func, which is:
template <typename A>
void func(Foo1<A> foo)
and if Something is specialized with Bar2, then func should be:
template <typename A, typename B>
void func(Foo2<A, B> foo)
However, this straightforward approach doesn't work, because clang complains (you need to instantiate Something<BarX> to make clang to report this error):
error: pack expansion used as argument for non-pack parameter of alias template void func(typename BAR::template Foo<P...> foo) {
So it seems that alias templates are not 100% transparent (I found some discussion about this: CWG 1430, that this is by design).
Are the any workarounds for this problem?
(gcc compiles this code, but according to CWG 1430, this might be unintended)
CodePudding user response:
Workaround is to make the alias variadic:
struct Bar1 {
template <typename... Ts>
using Foo = Foo1<Ts...>;
};
struct Bar2 {
template <typename... Ts>
using Foo = Foo2<Ts...>;
};
