How does operator overload resolution work when there is a new initializer sequence?

Given the following code:

#include <iostream>
#include <vector>

template <typename Source>
class ConvertProxy
{
    Source const* m_source;
public:
    ConvertProxy( Source const& source )
        : m_source( &source )
    {
    }

    template <typename Dest>
    operator Dest() const
    {
        return Dest(m_source->begin(), m_source->end());
    }
};

template <typename Source>
ConvertProxy<Source> convert( Source const& source )
{
    return ConvertProxy<Source>( source );
}

int
main()
{
    std::vector<int> src;
    for ( int i = 0; i != 5; ++ i ) {
        src.push_back( i );
    }
    std::vector<double> dest = convert( src );   /* XXX */
    for ( std::vector<double>::const_iterator i = dest.begin(), e = dest.end();
            i != e;
            ++ i ) {
        std::cout << *i << std::endl;
    }
    return 0;
}

Is this legal in C ++ 11, or is a line labeled XXXambiguous?

The same question, but with the line marked is replaced by:

std::vector<double> dest( convert( src ) );

or

std::vector<double> dest;
dest = convert( src );

In pre-C ++ 11, I think the second was illegal, but the other two definitely weren't.

FWIW: g ++ (4.8.2) accepts the first, but not the second (with -std=c++11; otherwise, it accepts the first and third, but not the second). VS 2013 accepts all of them, but Intellisense notes that they are all wrong (which aroused my interest: you get beautiful red markings in the scroll bar, with the characters underlined in red, but the code compiles fine). In other words: three compilers and three different behaviors.

( , , : , , .)

+4
1

, , , ++ 11 - .

; :

template <typename T, typename A, template <typename, typename> class Dest>
operator Dest<T, A>() const 
{ 
    return Dest<T, A>(m_source->begin(), m_source->end()); 
}

,

[T = double, A = allocator<double>, Dest = vector],

gcc-4.1.2 clang-3.4 - -std=c++11 .

0

Source: https://habr.com/ru/post/1527359/


All Articles