In Where in the C++11 standard does it prohibit 'template <typename T> class A {...}; template <typename T> class A<int> {...};' (if anywhere)?, it's been confirmed that the following syntax is disallowed in the C++11 standard:
/* invalid C++ */
template <typename T>
class A
{
public:
T t;
};
// phony "full specialization" that mistakenly attempts
// to introduce a *new* template parameter
template <typename T>
class A<int>
{
public:
int i;
T t;
};
With full understanding that the above syntax does not represent valid C++, I nonetheless could imagine a syntactically unambiguous use of the above code snippet, as follows:
A<float> a1;
A<int><double> a2;
a1.t = 2.0f;
a2.i = 2;
a2.t = 2.0;
It would seem syntactically and semantically unambiguous for C++ to support the syntax above.
(If the intended semantics is not clear to anybody, please post a comment and I will explain.)
I would describe this syntax as "introducing a new template parameter in a full specialization".
In this imagined scenario of a C++ compiler modified to support the above syntax and semantics, the compiler would see A<int> a2;
and recognize that the attempted instantiation matches the primary template; it would then search for specializations and find and select the full specialization A<int>
(ignoring the <double>
); it would then note that this full specialization introduces a new template parameter T
which in the case of the declared variable a2
is a double
.
If I'm right that the above syntax and semantics is unambiguous, then I'd like to know why this is not part of C++. I can think of three reasons, but perhaps the answer is different or more complicated.
- There are (almost) no real-world scenarios where this would be useful
- It's too complex for current compilers to be asked to support
- There are too many potential conflicts with other language features that would necessitate many new rules
- Actually, a fourth possibility - the above syntax and semantics would be useful in some real-world scenarios and could be reasonably included in the standard, but it's just not part of the current standard.
I'd like to know why this isn't supported in C++ - am I correct that one of my bullet points provides the answer?
A<int><double>
would thoroughly defeat the point of specialization. Just make a new class namedB
with two template parameters, and use it asB<int, double>
. The whole point of specialization is that the client doesn't need to do anything special or even know it exists - it just uses the syntax of the primary template, and the specialization automatically kicks in as necessary. – Igor TandetnikA
and useA<int><double>
(rather than introducing a new class,B
), then you could automatically disable (via compiler errors) all theA
specializations of the formA<T1><T2>
simply by commenting out the primary template forA
. Also, by usingA
it would be clear that you mean the same thing semantically in some sense everywhere you useA
. – Dan NissenbaumA<T1><T2>
specializations in that hypothetical world of yours, then what's left? Is there something namedA
that still could somehow be used? – Igor Tandetnik