If anyone can give me some insight as to why this code fails to
compile, I would be most appreciative. I have only been able to test
it with gcc 3.4.4 and gcc 4.2.1, which both fail with different errors
(details below).
//////// begin test_bug.cpp
// Standard Type2Type from Alexandrescu's Modern C++ Design
template<typename T>
struct Type2Type
{
typedef T OriginalType;
};
// Base for mix-in classes
template<typename Mixin>
struct MixinBase
{
virtual ~MixinBase() {}
virtual void mixinVirtual() {}
static void mixinStatic(Type2Type<Mixin>) {}
};
struct MixinA
: public MixinBase<MixinA>
{
};
struct MixinB
: public MixinBase<MixinB>
{
};
// Base for mix-in classes in an object
template<typename ObjType, typename Mixin>
struct ObjMixin
: public Mixin
{
void mixinVirtual()
{
// Call mixinStatic in our base object (the one that derives
from us)
// This should call the function defined in ObjType itself if
one exists
// or the default in MixinBase if not (behavior similar to a
virtual function
// but without the actual dynamic dispatch).
ObjType::mixinStatic(Type2Type<Mixin>());
}
};
// Object composed of two mix-in classes
struct TestObj
: public ObjMixin<TestObj, MixinA>
, public ObjMixin<TestObj, MixinB>
{
} testInstance;
//////// end test_bug.cpp
g++ 4.2.1 rejects this with the following output:
----------
% g++ test_bug.cpp
test_bug.cpp: In member function 'void ObjMixin<ObjType,
Mixin>::mixinVirtual() [with ObjType = TestObj, Mixin = MixinA]':
test_bug.cpp:44: instantiated from here
test_bug.cpp:35: error: reference to 'TestObj::mixinStatic' is
ambiguous
test_bug.cpp:15: error: candidates are: static void
MixinBase<Mixin>::mixinStatic(Type2Type<Mixin>) [with Mixin = MixinB]
test_bug.cpp:15: error: static void
MixinBase<Mixin>::mixinStatic(Type2Type<Mixin>) [with Mixin = MixinA]
test_bug.cpp: In member function 'void ObjMixin<ObjType,
Mixin>::mixinVirtual() [with ObjType = TestObj, Mixin = MixinB]':
test_bug.cpp:44: instantiated from here
test_bug.cpp:35: error: reference to 'TestObj::mixinStatic' is
ambiguous
test_bug.cpp:15: error: candidates are: static void
MixinBase<Mixin>::mixinStatic(Type2Type<Mixin>) [with Mixin = MixinB]
test_bug.cpp:15: error: static void
MixinBase<Mixin>::mixinStatic(Type2Type<Mixin>) [with Mixin = MixinA]
----------
This would at least appear to be wrong, since the different values for
Mixin (MixinA and MixinB) should disambiguate the call.
g++ 3.4.4 rejects it with the following output:
----------
g++ test_bug.cpptest_bug.cpp: In member function `void ObjMixin<ObjType,
Mixin>::mixinVirtual() [with ObjType = TestObj, Mixin = MixinA]':
test_bug.cpp:40: instantiated from here
test_bug.cpp:32: error: `mixinStatic' is not a member of `TestObj'
test_bug.cpp: In member function `void ObjMixin<ObjType,
Mixin>::mixinVirtual() [with ObjType = TestObj, Mixin = MixinB]':
test_bug.cpp:40: instantiated from here
test_bug.cpp:32: error: `mixinStatic' is not a member of `TestObj'
----------
Again this seems wrong, removing ObjMixin<TestObj, MixinBfrom the
definition of TestObj results in correct compilation under both
versions, so clearly mixinStatic is found as a member of TestObj in
some cases.
Thanks in advance for any insight into what could be going on here.