xmllmx wrote:
Dear all,
C++98 14.3.1 explicitly says as follows:
"A local type, a type with no linkage, an unnamed type or a type
compunded from any of these types shall not be used as a template-
argument for a template type-parameter."
And the Standard also immediately gives an example:
/*-- Source Code Begin --*/
template<class T> class X {};
void f()
{
struct S {};
X<S> x3; // error: local type used as template-argument
}
/*-- Source Code End --*/
Nevertheless, the source code should can be correctly compiled by
Visual C++. Moreover, C++0x 14.4.1 explicitly says differently as
follows:
"A template-argument for a template-parameter which is a type
shall be a type-id."
C++0x 14.4.1 also immediately gives some examples as follows:
/*-- Source Code Begin --*/
template<class T> class X {};
template<class T> void f(T t) {}
struct {} unnamed_obj;
void f()
{
struct A {};
enum { e1 };
typedef struct { } B;
B b;
X<A> x1; // OK
X<A*> x2; // OK
X<B> x3; // OK
f(e1); // OK
f(unnamed_obj); // OK
f(b); // OK
}
/*-- Source Code End --*/
Obviously, both of the most popular C++ compiler and C++0x relax
the restrictions put by C++98.
In my view, the new rules without restrictions are intuitive, easy
to use for programmers and easy to implement for compilers. What
makes me most puzzled is the hidden reason for the authors of
C++98 to put such counterintuitive restrictions on compilers and
on us innocent programmers? What's the WHY behind the C++98
restrictions?
The restriction was there beacuse nobody spent enough time to
figure out what it should mean. If you have two struct S in two
different functions, will that get you one or two X<S>'s?
10 years later, the committee has figured this out , and agreed
that template<class T> class X {};
void f()
{
struct S {};
X<S> x3; // error: local type used as template-argument
}
can be compiled as
template<class T> class X {};
namespace
{
struct S {};
}
void f()
{
X<S> x3; // error: local type used as template-argument
}
which has been legal and well defined all along.
S. They would be different types S, right? I.e. it is not quite like