Reputation: 329
Suppose we have a class
template <int ... values>
struct foo;
now I have a function
template<typename foo_type, typename U>
void bar(foo_type a, U b);
where foo_type
is basically foo
. My issue is that, I do not want the variable a
in the bar
function. I want to be able to call the function like so
bar<foo<6,5,7,8,0>>(42);
but have all the parameters of foo
available to me in bar
. I tried changing the function to
template<template<int...> class foo_type, int ... args, typename U>
void bar(U b)
but this simply does not work. How can I do this? How can I change bar
to the above way and still access the parameters in foo
? Basically I want to do generic computation on those list at runtime
// within the body of bar
constexpr int[sizeof...(args)] = {args...};
where args
is parameters of foo
.
Upvotes: 0
Views: 67
Reputation: 302718
How opposed are you to having foo
be an argument? Personally, I like having everything be an argument. Just wrap it in an empty type:
template <class T> struct tag_type { using type = T; };
template <class T> constexpr tag_type<T> tag{};
So that you can still template on the ints...
:
template<int... Is, typename U>
void bar(tag_type<foo<Is...>> a, U b) {
constexpr int stuff[sizeof...(Is)] = {Is...};
// ...
}
Instead of calling bar<foo<6,5,7,8,0>>(42);
you'd call bar(tag<foo<6,5,7,8,0>>, 42);
, which is close enough.
To get exactly what you want, you can forward the former call to the latter:
namespace details {
template<int... Is, typename U>
void bar(tag_type<foo<Is...>> a, U b) {
constexpr int stuff[sizeof...(Is)] = {Is...};
// ...
}
}
template <typename foo_type, typename U>
void bar(U b) {
details::bar(tag<foo_type>, b);
}
And now it's the best of both worlds.
Upvotes: 2
Reputation: 62553
I believe, the question is about extracting template arguments from given foo
type? If I am correct, here is the solution.
You will have to partially specialize a helper class, like following:
template <int ... values>
struct foo { };
template<class T>
struct bar_helper {};
template<int... values> struct bar_helper<foo<values...> > {
template<class T> static void bar(T ) {
// Use values... here
}
};
template<class foo_type, class U>
void bar(U b) {
bar_helper<foo_type>::bar(b);
}
void check() {
bar<foo<2, 3, 4, 5, 6> >(42);
}
Upvotes: 0