User error or g++ disambiguation bug?

Discussion in 'C++' started by spamfree@mailinator.com, Aug 21, 2007.

  1. 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.
     
    , Aug 21, 2007
    #1
    1. Advertising

  2. Duane Hebert Guest

    <> wrote in message
    news:...
    > 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
     
    Duane Hebert, Aug 21, 2007
    #2
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Xenos
    Replies:
    2
    Views:
    689
    Dave Moore
    Apr 29, 2004
  2. John Collins

    Template disambiguation

    John Collins, Dec 28, 2004, in forum: C++
    Replies:
    1
    Views:
    463
    Victor Bazarov
    Dec 29, 2004
  3. =?windows-1250?Q?Petr_Jake=9A?=
    Replies:
    11
    Views:
    1,524
  4. Nomen Nescio

    User error or g++ disambiguation bug?

    Nomen Nescio, Aug 21, 2007, in forum: C Programming
    Replies:
    10
    Views:
    589
    CBFalconer
    Aug 24, 2007
  5. bonzo
    Replies:
    1
    Views:
    323
    bonzo
    Oct 15, 2008
Loading...

Share This Page