Re: Calling base members of template class
Al schrieb:
template <typename T>
struct Base { virtual void Foo() {} };
struct Derived : public Base<int> {
virtual void Foo() { Base::Foo(); } // version1
virtual void Foo() { Base<int>::Foo(); } // version2
};
It seems my compiler (VC++8) lets me omit the template suffix when
calling a method in the Base class from Derived (version1). My questions
are:
a) Are both versions legal C++?
Yes, they are. But "template suffix" is no standard nomenclature,
officially this is called "used with a template-argument-list".
b) Are both versions identical (in /this/ case)?
Yes, they are.
c) Is omitting the suffix always identical to including it?
No, it is not. But if you omit the template-argument-list within the
scope of a specialization, it is equivalent to the injected class-
name
followed by the template-arguments of that specialization, see
14.6.1/2.
14.6.1/2a describes essentially your use-case:
"The injected-class-name of a class template or class template
specialization can be used either with or without a template-argument-
list
wherever it is in scope.[..]"
Differences occur e.g. in multiple inheritance situations (v.i.).
The reason I ask is because in a project that I am working on (which
uses virtual and multiple inheritance), the first version consistently
causes runtime reading violations while the second one magically works.
Could it be a compiler bug?
Most probably.
Also, it seems like when doing something like this:
struct Derived : public Base<int>, public Base<float> {};
Omitting the suffix /still/ compiles, and causes the Base<int> version
to be called. Is that well-defined behavior?
Nope, if this compiles, it's a compiler bug, because in this
example the injected class-name causes an ambiguity. This
is precisely described by 14.6.1/2b:
"A lookup that finds an injected-class-name (10.2) can result in
an ambiguity in certain cases (for example, if it is found in more
than one base class). If all of the injected-class-names that are
found refer to specializations of the same class template, and if
the name is followed by a template-argument-list, the reference
refers to the class template itself and not a specialization thereof,
and is not ambiguous."
Thus in this case you must use the full template-argument-list
to resolve the ambiguity inside Derived.
Greetings from Bremen,
Daniel Kr|gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]