繁体   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