Why is the following declaration invalid?
template<template<typename> typename T>
struct S {};
I would assume this was valid since the following is valid:
template<template<typename> class T>
struct S {};
and what I can read from the standard in [gram.temp] it appears to be valid, but gcc gives me the following output:
prog.cpp:4:38: error: expected 'class' before 'T'
template<template<typename> typename T>
^
Basically, "because the standard says so." C++11 14.1/1 lists the syntax for type-parameter:
type-parameter:
class
...
optidentifieropt
class
identifieropt=
type-id
typename
...
optidentifieropt
typename
identifieropt=
type-id
template
<
template-parameter-list>
class
...
optidentifieropt
template
<
template-parameter-list>
class
identifieropt=
id-expression
As you can see, only class
is allowed for template template parameters.
My guess for the rationale is that any type can be used as a type argument, including non-class types. But before C++11, there was no such thing as a "non-class type template"—the only type templates were class templates.
This has changed with C++11's alias templates, but the template template parameter syntax has obviously not kept up. Nevertheless, in a post-C++11 (actually post-C++14) draft N4296, this restriction is actually lifted and template <class> typename
is valid template template parameter syntax.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With