Reputation: 131445
I have defined the class
template <typename... Ts> struct Bar {
using inner_type = /* whatever */;
};
Now, I need to define a templated class Foo
whose template parameters are some parameter pack, and a value of type Bar::inner_type
instantiated for that parameter pack. Unfortunately I can't seem to be able to do it. If I define it this way:
template <Bar<Ts...>::inner_type SomeValue, typename... Ts> struct Foo { };
the compiler doesn't recognize Ts
when it's used, since it hasn't see the parameter pack yet; but if I define it this way:
template <typename... Ts, Bar<Ts...>::inner_type SomeValue> struct Foo { };
the compiler sneers at my attempt to use a parameter pack before other template parameters.
So how can I do this?
Note: In case it matters, this failed for me with GCC 4.9.3.
Upvotes: 5
Views: 252
Reputation: 50540
You can partially specialize your struct:
template<typename...>
struct Bar { using inner_type = int; };
template <typename T, typename T::inner_type T>
struct Foo;
template <typename... Ts, typename Bar<Ts...>::inner_type SomeValue>
struct Foo<Bar<Ts...>, SomeValue> { };
int main() {
Foo<Bar<int>, 3> foo;
}
This way Ts
parameter pack is deduced and Foo
expects the second template parameter to be of type Bar<Ts...>::inner_type
.
Upvotes: 2
Reputation: 273
If I understood your problem correctly, you can do something like this:
template <typename... Ts> struct Bar {
using inner_type = /* whatever */;
};
template <typename... Ts> struct Foo {
using inner_type = typename Bar<Ts...>::inner_type;
};
Upvotes: 0
Reputation: 75688
The best thing I could come up with:
template <class Inner, Inner Val, class... Args>
struct Foo {
static_assert(std::is_same<Inner, typename Bar<Args...>::inner_type>::value, "Wrong type");
};
You need to explicitly name the type.
Upvotes: 1
Reputation: 312
does this solve the issue?
#include <type_traits>
using namespace std;
template <typename... Ts> class Bar {
public:
using inner_type = int;
};
template <typename... Ts> class Foo {
using bar_inner_type = typename Bar<Ts...>::inner_type;
static_assert(is_same<int, bar_inner_type>::value,"");
};
Upvotes: 0