VS 2015更新3删除拷贝赋值操作符错误
VS 2015 Update 3 error for deleted copy assignment operator
下面的代码在clang-3.8和gcc 4.9.3上可以很好地编译。
#include <vector>
#include <algorithm>
#include <iterator>
class foo
{
};
class MyVec {
public:
MyVec() {}
};
class MyInsert :
public std::iterator<std::output_iterator_tag, void, void, void, void>
{
protected :
MyVec &fV;
public :
explicit MyInsert (MyVec &v) : fV(v) {}
MyInsert & operator= (void *value)
{
return *this;
}
MyInsert & operator* () { return *this; }
MyInsert & operator++ () { return *this; }
MyInsert & operator++(int) { return *this; }
};
class test
{
public:
void method()
{
MyVec retv;
std::vector<const foo*> foovec;
std::transform(foovec.begin(), foovec.end(),MyInsert(retv),[](const foo*)->void* { return nullptr;});
}
};
int main(){
return 0;
}
但是,当在VS 2015 Update 3上编译时,它会失败,并显示以下错误信息。
c:program files (x86)microsoft visual studio 14.0vcincludexutility(458): error C2280: 'MyInsert &MyInsert::operator =(const MyInsert &)': attempting to reference a deleted function
testmytestsmain.cpp(33): note: compiler has generated 'MyInsert::operator =' here
c:program files (x86)microsoft visual studio 14.0vcincludealgorithm(926): note: see reference to function template instantiation '_Iter &std::_Rechecked<_OutIt,_OutIt>(_Iter &,_UIter)' being compiled
with
[
_Iter=MyInsert,
_OutIt=MyInsert,
_UIter=MyInsert
]
c:program files (x86)microsoft visual studio 14.0vcincludealgorithm(950): note: see reference to function template instantiation '_OutIt std::_Transform_no_deprecate1<const foo**,_OutIt,_Fn1>(_InIt,_InIt,
_OutIt,_Fn1 &,std::input_iterator_tag,std::_Any_tag)' being compiled
with
[
_OutIt=MyInsert,
_Fn1=test::method::<lambda_45e8626339fc29aadca2bf2dd3420511>,
_InIt=const foo **
]
c:program files (x86)microsoft visual studio 14.0vcincludealgorithm(960): note: see reference to function template instantiation '_OutIt std::_Transform_no_deprecate<_InIt,_OutIt,_Fn1>(_InIt,_InIt,_OutIt,
_Fn1 &)' being compiled
with
[
_OutIt=MyInsert,
_InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<const foo *>>>,
_Fn1=test::method::<lambda_45e8626339fc29aadca2bf2dd3420511>
]
testmytestsmain.cpp(45): note: see reference to function template instantiation '_OutIt std::transform<std::_Vector_iterator<std::_Vector_val<std::_Simple_types<const
foo *>>>,MyInsert,test::method::<lambda_45e8626339fc29aadca2bf2dd3420511>>(_InIt,_InIt,_OutIt,_Fn1)' being compiled
with
[
_OutIt=MyInsert,
_InIt=std::_Vector_iterator<std::_Vector_val<std::_Simple_types<const foo *>>>,
_Fn1=test::method::<lambda_45e8626339fc29aadca2bf2dd3420511>
]
]
我无法理解为什么它(VS编译器)无法找到复制赋值运算符,它接受void *
并在明确提供时返回MyInsert &
。
深入了解(通过跟踪错误消息)
c:program files (x86)microsoft visual studio14.0vcincludexutility
和
c:program files (x86)microsoft visual studio14.0vcincludealgorithm
也让我意识到实际的函数中,std::transformation
算法被调用,显式提供的拷贝赋值被调用,之后它进入_Rechecked
函数,进入xutility
头。
在这个函数中,调用了复制赋值操作符,它期望(输入为MyInsert&
,输出为MyInsert&
),由于没有找到,它将错误消息显示为attempting to reference...
。
这个分析正确吗?如果没有,那么为什么不能编译在其他主要编译器上编译的代码?也许是一个bug?
p。S
我正在使用的当前工作是删除MyInsert
类中的引用成员和非引用成员。
我不明白为什么它(VS编译器)不能找到复制赋值运算符,它接受
void *
并在明确提供时返回MyInsert &
。
以void*
为形参的赋值操作符不是copy赋值操作符。
编译器尝试使用显然没有明确提供的复制赋值操作符。它也不是隐式提供的,因为有一个引用成员。
输出迭代器必须满足OutputIterator的要求,它必须满足 iterator 的要求,而 iterator 又必须满足CopyAssignable的要求,这就要求你有一个拷贝赋值操作符。这是MyInsert
所缺乏的。
为什么不能编译正在其他主要编译器上编译的代码?
虽然输出迭代器必须满足要求,但是没有要求标准库实现检查是否满足要求。
希望概念的正式规范将来会成为标准的一部分,以改进这种情况下的错误消息。
可能是bug?
错误是代码中缺少复制赋值操作符。VS和其他编译器在这方面都是符合标准的。
我正在使用的当前工作是删除MyInsert类中的引用成员和非引用成员。
通过删除reference成员,允许隐式声明复制赋值操作符。这就是为什么它有效。要在保持类型copy可赋值的同时继续引用对象,请使用普通指针代替引用。
- c++中的重载赋值操作符
- c++类继承和赋值操作符
- 带引用类成员的赋值操作符
- 复制构造函数,赋值操作符重载
- c++派生类赋值操作符
- 通过调用Move赋值操作符实现Move构造函数
- 带有映射的赋值操作符
- 单参数构造函数和赋值操作符
- 如何从复制赋值操作符调用复制构造函数
- 拷贝赋值操作出现分段错误
- c++复制构造函数,重载赋值操作符,方法get()
- 用于具有const数据成员的类的move和右值赋值操作符
- 类赋值操作符和复制构造函数
- 赋值操作符重载
- 影响正确性的move构造函数/赋值操作符示例
- 当类是子类时重载赋值操作符
- 如果没有定义Move语义(Move构造函数和Move赋值操作符),编译器是否默认优化
- 如何避免拷贝赋值操作符的双重自由或损坏(fasttop)
- VS 2015更新3删除拷贝赋值操作符错误
- 如何编写一个拷贝赋值操作符来处理引用