So, my motivation here is to determine whether the same named type declaration within several classes are the same type. In this example, I'm looking to see that all of Foo, Bar, and Baz have an internal type Q.
#include <type_traits>
template <typename N,typename ...Ns>
using equal_type_t = typename std::enable_if_t<(std::is_same_v<N, Ns> && ...), N>;
template <typename N>
using ExtractQ_t = typename N::Q;
template <typename ...Ns>
using EqualQ_t = equal_type_t<ExtractQ_t<Ns>...>;
int main()
{
struct Qness{};
struct Foo{using Q = Qness;};
struct Bar{using Q = Qness;};
struct Baz{using Q = Qness;};
using F = EqualQ_t<Foo,Bar,Baz>;
static_assert(std::is_same_v<F,Qness>);
return 0;
}
Tested in clang9 (praise be to godbolt).
The error reported is:
#1 with x86-64 clang 9.0.0
<source>:10:31: error: pack expansion used as argument for non-pack parameter of alias template
using EqualQ_t = equal_type_t<ExtractQ_t<Ns>...>;
I could probably solve this by way of doing some template recursion, but I'm trying to learn to use parameter pack expansion wherever possible.
Is this possible? Is this not an allowed context? If I separate out a few individual N types, it works fine:
template <typename N1,typename N2, typename N3, typename ...Ns>
using EqualQ_t = equal_type_t<ExtractQ_t<N1>,ExtractQ_t<N2>,ExtractQ_t<N3>>;
I have to be having a pre-coffee brain-fog and can't see where I might be hosing the syntax.
Is there an expansion variant of this that will work?