[英]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.