Alternating Template Parameters Pack

2020-07-22 17:28发布

问题:

How do I achieve a pack of alternating template parameters?

Something like this:

template< ( unsigned non_type, typename type )... >

Where the usage must be

my_class< 5U, float,
          6U, std::string >

I don't want to change the order nor do I want to have a wrapper around it as a pair during usage. Obviously, if it devolves into some sort of a pair in my own internal implementation, that's fine.

回答1:

The thing to remember about templates is that they're not macros. They are not copying tokens around. They're actual C++ constructs. Every template parameter must be of a specific kind: a type parameter, a non-type parameter, or a template-template parameter which must have its template parameter list specified. The kind of a template parameter lets the compiler know whether the use of that parameter in a particular place makes sense.

For example, this is potentially meaningful code:

template<auto value>
auto foo() {return value + 1;}

This is obviously nonsense:

template<typename value>
auto foo() {return value + 1;}

The compiler doesn't even have to wait for you to instantiate the template to shut you down.

The only way to use a parameter pack is to expand it in some location. And expanding a parameter pack applies the pattern which uses the pack to all elements of the pack. It's very difficult to construct a scenario where types and values could both fit into the syntax of the pattern.

It isn't impossible to do so, of course. For example, (pack(something), ...) could be legitimate for both type and non-type template parameters. But they won't be doing the same thing. For values, it will be invoking any available operator() on the type; for types, it will be calling a constructor to create a prvalue.

The most generically useful case would be to expand a heterogeneous pack directly into a template argument list.

However, all of this is sophistry, because C++ templates aren't macros. Template parameters must be of a well-defined kind so that the compiler can know if they are being used properly. And this includes parameter packs. So all elements of a pack must be of the same kind. What you want would be called "universal template parameters", but those are only a proposal at present.



标签: c++ c++17 c++20