Re: using and ambiguous call
On Jan 8, 11:18 pm, va...@krautgames.de wrote:
is this legal c++ code?
template <typename BaseT> struct A
{
BaseT& this_() { return *static_cast<BaseT*>(this); }
template <typename T> void Foo() { this_().Bar<T>(); }
The above line is, I believe, illegal. The call to Bar is in a
dependent context, so Bar can't be looked up until
instantiation. The compiler, however, must know that Bar is a
template in order to correctly parse the code in the template
definition. So the function call should be:
this_().template Bar<T>() ;
But none of my compilers seem to complain, so I'm not sure. I'm
also unable to find where this is discussed in the standard at
the moment. (My understanding is that without the additional
"template", the compilers should interpret the < as "less than",
and not as opening a template argument list. And of course,
<user_symbol> <less_than> <type_name> cannot possibly be legal.)
template <typename T> void Bar() { }
template <typename T> void Bar(i32) { }
Not sure what i32 is, here. I used "int" when I experimented.
};
struct B : public A<B>
{
using A<B>::Bar;
template <typename T> void Bar() { }};
//..
B test; test.Foo<int>();
when using such a construction I got mixed results on various
compiler. Often I get an ambiguous call to overloaded function error
(A<B>::Bar() vs B::Bar()). Sometime it seem to make a difference when
using template member function or non-template member function.
Of the compilers I have available, two (g++ and Sun CC) have no
problems with your code, calling B::Bar(), as expected. VC++
seems to have problems with the using declaration, which results
in the ambiguity you mention. (It would seem that the compiler
is including all of the functions Bar from the base class,
rather than just those which aren't hidden.) Drop the using,
however, and it works. This is a bug, but the simple
work-around would be to drop the using, and also define Bar(i32)
in B.
If it is not legal, why not? Any ideas for good workarounds? I have
template member functions for which i want default implementations and
helpers/wrappers in the base class. Several directly from this base
class derived classes only implementing a subset of the default
implementation. Any ideas?
Legal or not, if it doesn't work with the compilers you have to
support, you have to change it. With the compilers I have
access to, the only one which causes a problem is VC++, and
dropping the using seems to solve the problem there. I would
also add the "template" mentionned above, since I suspect that
the code will fail to compile otherwise with some newer
compilers.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34