繁体   English   中英

赋值运算符重载具有类似的转换(仅在VS中)

[英]Assignment operator overloads have similar conversions (only in VS)

我有一个有三个类(A,B和C)的类层次结构。 A和B是基类,使用派生类型进行参数化。 C类来自A和B两者。

类B为类型A的对象提供赋值运算符,而类C using super::operator=声明继承此赋值运算using super::operator=

当我从类型A的对象在类B中定义构造函数时,我得到错误: 两个重载在Visual Studio 2013中有类似的转换 (C2666),但我没有在gcc(4.8.2)中收到任何错误或警告,clang(3.4)和intel icc(Studio 2015)。 (用-Wall -pedantic编译)

这里是简化的例子:

template <class Model> struct A {};

template <class Model> struct B
{
    B() {}; // default constructor

    // copy constructor for objects of type A
    template <class M> 
    B(A<M> const&) {} 

    // assignment operator for objects of type A
    template <class M>
    Model& operator=(A<M> const& rhs)
    {
        return static_cast<Model&>(*this);
    }
};

struct C : public B<C>, public A<C>
{
    typedef B<C>  super;

    // copy assignment operator
    C& operator=(C const& rhs) { return *this; }

    // adopt assignment operator for A<C> from super-class
    using super::operator=;
};

int main()
{
    C c;
    A<C> a;
    c = a;
}

如果我用非模板化的类替换模板化的类A,它也可以在Visual Studio中编译而不会出错 - 但这不是它可以解决的方式。

我的问题是 :这个结构是否符合标准,或错误信息是否正确? B中的复制构造函数的explicit说明符是否有助于解决问题?

顺便说一下:在Visual Studio中,我得到了警告指定了多个赋值运算符 (C4522),因为C类中的复制赋值运算符。有人可以解雇我,为什么这应该是个问题?

GCC和CLANG是正确的,MSVC是错误的:

预期的行为是什么:

陈述c=a; 使用您在B定义的operator= ,因为A<C>不一定是C 所以让我们通过手动执行类型替换来记下operator= of B<C>的声明:

template <class M> 
C& operator=(A<M> const& rhs)

由于aA<C> ,此模板的明显隐式实例化候选者将是:

 C& operator=(A<C> const& rhs)

这实际上是唯一可能的实例化(您可以通过显示typeinfo来验证GCC是否使用它)。

什么是MSVC试图做的?

如果您将C类简化为更简约的形式,您仍然会收到错误

struct C : public B<C>   // single inheritance
{   using B<C>::operator=; };  // nothing else

实际上问题是由构造函数B(A<M> const&)

  • 注释掉,代码将编译
  • 使它明确 ,代码也将编译

MSVC错误地识别出成员函数的隐式特化的第二个potental候选者。 由于此构造函数允许从A<M>隐式转换为B<C> ,因此候选者是:

 C& operator=(B<C> const& rhs)

但根据C ++标准,编译器根本不应该设想这个:

14.8.1 / 6: 如果参数类型不包含参与模板参数推导的模板参数则将对函数参数执行隐式转换,以将其转换为相应函数参数的类型

所以这显然是MSVC的一个错误。

顺便说说:

关于多个assignemnt运营商的警告只是一个信息 显然,MS认为这可能是导致错误的常见原因。 现在到了核心问题......

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM