User error or g++ disambiguation bug?

G

Guest

Hello,

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.cpp

test_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, MixinB> from 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.
 
D

Duane Hebert

Hello,

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.cpp

test_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, MixinB> from 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.

Fails Comeau online compiler as well but the error messages may
be a bit clearer:


Comeau C/C++ 4.3.9 (Mar 27 2007 17:24:47) for ONLINE_EVALUATION_BETA1
Copyright 1988-2007 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 34: error: "MixinBase<Mixin>::mixinStatic [with
Mixin=MixinA]"
is ambiguous
ObjType::mixinStatic(Type2Type<Mixin>());
^
detected during instantiation of "void ObjMixin<ObjType,
Mixin>::mixinVirtual() [with ObjType=TestObj,
Mixin=MixinA]"

"ComeauTest.c", line 34: error: "MixinBase<Mixin>::mixinStatic [with
Mixin=MixinA]"
is ambiguous
ObjType::mixinStatic(Type2Type<Mixin>());
^
detected during instantiation of "void ObjMixin<ObjType,
Mixin>::mixinVirtual() [with ObjType=TestObj,
Mixin=MixinB]"

2 errors detected in the compilation of "ComeauTest.c".
In strict mode, with -tused, Compile failed
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top