[cfe-dev] Strange phenomenon with conversion operator and call of overloaded method

Jonathan Sauer jonathan.sauer at gmx.de
Tue May 31 05:20:19 PDT 2011


Hello,

while fooling around with conversion operators, I stumbled upon the following:

struct Foo { };     // (A)
//using Foo = int;    // (B)

template <typename T>
class A {
    public:
        operator const T&() const { return m_t; }
        
    private:
        T   m_t;
};

static void bar(Foo&&) { }  // (C)
static void bar(const Foo&) { }

int main(int, char**)
{
    A<Foo>              a;
    bar(a);
    bar((const Foo&) a);  // (D)
}


Compiling this program with clang r132331 in C++0x mode results in the following error message:

clang.cpp:19:9: error: no viable conversion from 'A<Foo>' to 'Foo'
    bar(a);
        ^
clang.cpp:1:8: note: candidate constructor (the implicit copy constructor) not viable: no known
      conversion from 'A<Foo>' to 'const Foo &' for 1st argument
struct Foo { };     // (A)
       ^
clang.cpp:7:9: note: candidate function
        operator const T&() const { return m_t; }
        ^
clang.cpp:13:22: note: passing argument to parameter here
static void bar(Foo&&) { }  // (C)


First of all, clang does not tell why the noted candidate function is not viable. Second of all,
for some reason clang does not consider the overload bar(const Foo&), even though it would match.

When replacing line (A) with line (B) (making Foo an int instead of a class), the code compiles.
This is really strange.

When commenting out line (C) (making bar non-overloaded), the code compiles as well.

Helping the compiler as in line (D) also results in a successful compile.

Why does this happen?


With many thanks in advance,
Jonathan





More information about the cfe-dev mailing list