The following code compiles in visual studio 2015 (even with /Za option). It doesn't compile on gcc and clang.
struct A
{
};
template<typename T>
struct B
{
void f()
{
}
};
template<typename T>
struct C : B<T>
{
void f()
{
}
void g()
{
B::f();
}
};
int main()
{
C<A> c;
c.g();
return 0;
}
gcc - error: 'template struct B' used without template parameters
clang - error: 'B' is not a class, namespace, or enumeration
Which compiler is compliant to standard specifications? Any ambiguity in the specs?
Edit
I've added f()
in C
to have a more pertinent example.
Normally to call a base class function in this case you would write:
this->f();
If f
and g
were both static, you would of course not be able to do this, so instead you could write
B<T>::f();
This works because B
is already in scope at the declaration of C
, so the compiler already knows it's a template. If you do B::f()
alone, the compiler will give you an error because it knows B
is a template so it is supposed to have template arguments.
You might be wondering why you are allowed to omit the template arguments inside the definition of B<T>
but not inside the definition of C
. To understand this, you need to know that every class has an injected-class-name that behaves like a typedef declared at the very beginning of the class definition. So it is as though the definition of B
started with
typedef B<T> B;
Using B
inside the definition of B<T>
will find the injected-class-name , not the template. But when you are inside C
, this B
is not visible since it is declared inside B<T>
, which is a dependent base class, and dependent base class scopes are not searched during unqualified name lookup (and B
is on the left of ::
, so the lookup of B
is unqualified). This also works:
C::B::f();
In this case, the injected-class-name C
is found, and it refers to the dependent type C<T>
, so the lookup of B
will search inside the dependent base class B<T>
and find the desired injected-class-name .
问题出在struct C
,在没有模板参数的情况下调用B
的函数f
。
The compiler doesn't know the B
you're referring to in B::f();
, try changing it to B<T>::f();
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.