jeudi 5 mai 2016

function template overload resolution with user defined conversion operator

What is the correct output for following code according to C++11 standard?

#include <iostream>

template <typename X>
class A
{
public: 
    A()
    {
        std::cout << "A::A" << std::endl;
    }
    A(const A<X>&)
    {
        std::cout << "A::A(const A<X>&)" << std::endl;
    }
    A<X>& operator = (const A<X>&)
    {
        std::cout << "A::opeartor =(conat A&)" << std::endl;
        return *this;
    }
};

void* GetData()
{
    // return data based on some condition
    static A<int> a;
    return &a;
}

class P
{

public:
    template <typename T>
    operator T&()
    {
        void* pData = GetData();             
        std::cout << "P::operator T&()" << std::endl;
        return *(reinterpret_cast<T*>(pData));
    }

    operator A<int>()
    {
        std::cout << "P::opeartor A<int>" << std::endl;
        return A<int>();
    }
};

int main(int /*argc*/, char** /*argv*/)
{
    P objP;
    A<int> objA = objP; // case 1
    objA = objP; // case 2
    return 0;
}

clang and gcc produce following output.

P::opeartor A<int>
A::A
A::A
P::operator T&()
A::opeartor =(conat A&)

VS 2015 generates output as shown below.

A::A
P::operator T&()
A::A(const A<X>&)
P::operator T&()
A::opeartor =(conat A&)

Case 1

VS2015 picks template version where as gcc and clang picks non template version.

Case 2

All three compilers pick template version.

How can we explain this behavior with reference to C++ 11 standard?

Aucun commentaire:

Enregistrer un commentaire