簡體   English   中英

在新的初始化序列存在的情況下,運算符重載解析如何工作?

[英]How does operator overload resolution work in the presence of the new initializer sequence?

給出以下代碼:

#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;
}

這在C ++ 11中是合法的,還是標記為XXX模糊的行?

同樣的問題,但標記的行代替:

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

或者

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

在前C ++ 11中,我認為第二個是非法的,但其他兩個肯定不是。

FWIW:g ++(4.8.2)接受第一個,但不接受其他兩個(使用-std=c++11 ;否則它接受第一個和第三個,但不接受第二個)。 VS 2013接受所有這些,但Intellisense標記所有這些都是錯誤的(這引起了我的興趣:你在滾動條中得到一個漂亮的紅色標記,下划線用紅色標出,但代碼編譯完美)。 換句話說:三個編譯器和三個不同的行為。

(對於那些想知道原因的人來說:這是獲取上下文的標准習慣用語 - 例如,在重載決策中涉及的任務的左側)。

編譯代碼的一邊有歧義,必須首先解決,我不認為C ++ 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標志。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM