9

Say you have a tuple type and you want to extract its template parameter pack in order to instantiate another template. If that is a type template, then I can have a utility like this:

template < typename Tuple, template <typename...> typename What >
struct PutTupleInT;

template < typename... Types, template <typename...> typename What >
struct PutTupleInT<std::tuple<Types...>, What>
{
    using Result = What<Types...>;
};

But what if the desired template is a variable template? While template <typename...> typename What is the "placeholder" for a type template, then what is the "placeholder" for a variable template?

I've tried the following for clang-4.0.0 (the only compiler by now that supports non-type template parameters with auto type), but it failed. Actually I am not sure if this is a correct syntax for C++17.

template < typename Tuple, template <typename...> auto What >
struct PutTupleInV;

template < typename... Types, template <typename...> auto What >
struct PutTupleInV<std::tuple<Types...>, What>
{
    static constexpr auto value = What<Types...>;
};
Vahagn
  • 4,670
  • 9
  • 43
  • 72

2 Answers2

6

I don't think you can do that. Quoting N4606:

§14.3.3 [temp.arg.template]/1

A template-argument for a template template-parameter shall be the name of a class template or an alias template, expressed as id-expression.

A variable template doesn't fit this requirement.


You could cheat a little and use a proxy type to select the template:

template < typename Tuple, class Proxy>
struct PutTupleInTV;

template < typename... Types, class Proxy>
struct PutTupleInTV<std::tuple<Types...>, Proxy>
{
    static constexpr auto value = Proxy::template value<Types...>;
};

and then for

template<typename...> struct foo{};
template<typename... Ts> constexpr foo<Ts...> foo_v{};
struct use_foo
{
    template<typename... Ts>
    static constexpr auto value = foo_v<Ts...>;
};

you could say

PutTupleInTV<tup, use_foo>::value

live demo

krzaq
  • 16,240
  • 4
  • 46
  • 61
  • The cheat actually doesn't help much, as it requires the variables to be named "value" and to be placed in a struct. – Vahagn Oct 24 '16 at 15:57
  • @Vahagn yes, you'd have to make proxy structs yourself. I don't see a way around this (doesn't mean there's none, I just don't know of any) – krzaq Oct 24 '16 at 15:59
0

PutTupleInTV is not the same name as PutTupleInV. You are not specializing the template PutTupleInV but using specializing syntax to create something new, called PutTupleInTV.

yeoman
  • 1,671
  • 12
  • 15