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