Defining a class or an enumeration in an alias-declaration that is part of a template alias is forbidden by [dcl.typedef]/2:
A typedef-name
can also be introduced by an
alias-declaration.
...
The
defining-type-specifier-seq
of the
defining-type-id
shall not define a class or enumeration if the
alias-declaration
is the declaration of
a
template-declaration.
The latter was introduced as CWG issue 1159 was accepted, as part of FCD N3092.
The comments and proposed resolution of the associated N3092 comment US 74 does provide some rationale as to why this restriction was introduced [emphasis mine]:
Comment (ID) US 74
Comment
An alias-declaration allows a class or enumeration type to be defined
in its type-id (7.1.6p3). However, it's not clear that this is
desirable when the alias-declaration is part of a template alias:
template<typename T> using A =
struct { void f(T) { } };
Proposed resolution
Either prohibit the definition of classes and enumerations in
template aliases, or prohibit the use of template parameters in such
definitions, or add an example illustrating this usage.
Owner & issue
CWG 1159
Disposition
ACCEPTED
Definition of a class or enumeration is now prohibited in a template alias.
It would seem as if no one protested (convincingly enough) to prohibiting the definition of classes and enumerations in template aliases, implying that it's likely that no one was able to give a convincing example illustrating where this would be useful.
struct Foo
? Where and why do you need it? – Giltstruct Bar
? Why do you want anonymous classes? Also please note that a static assert on the base template definition that is false for every imaginary instantiation is UB. – Giltusing Bar = struct
vsstruct Bar
does not save any characters. It is a bit inconsistent, but I would not spend my time fixing something that's not broken. – Kerplunkusing Bar1 = struct Foo1 { /*Implementation*/ };
but nottemplate<class> using Bar2 = struct Foo2 { /*Implementation*/ };
as you geterror: types may not be defined in alias template declarations
, here is the inconsistency IMHO – Febrificusing Bar = struct { /*Implementation*/ };
vsstruct Bar { /*Implementation*/ }
you don't save any characters. And even if you would, you write code once, you read it multiple times, a few extra characters to save are nowhere nearly as important as having clean code. Also, on the inconsistency front: nobody cares, because nobody usesusing Foo = struct { /* ... */ }
. – Gilt