c++ - 删除复制赋值运算符的 VS 2015 Update 3 错误

标签 c++ c++11 visual-studio-2015

以下代码在 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.0\vc\include\xutility(458): error C2280: 'MyInsert &MyInsert::operator =(const MyInsert &)': attempting to reference a deleted function
test\mytests\main.cpp(33): note: compiler has generated 'MyInsert::operator =' here
c:\program files (x86)\microsoft visual studio 14.0\vc\include\algorithm(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.0\vc\include\algorithm(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.0\vc\include\algorithm(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>
        ]
test\mytests\main.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.0\vc\include\xutility

c:\program files (x86)\microsoft visual studio14.0\vc\include\algorithm

还让我意识到调用 std::transformation 算法的实际函数,调用显式提供的复制赋值,之后它进入 _Rechecked 函数,然后它开始进入 xutility header 。

在此函数中,调用了复制赋值运算符,它期望(输入为 MyInsert& 并输出为 MyInsert&),由于找不到,因此将错误消息显示为正在尝试引用...

这个分析正确吗?如果没有,那么为什么不能编译在其他主要编译器上编译的代码?也许是一个错误?

附言

我目前使用的解决方法是删除 MyInsert 类中的引用成员和非引用成员。

最佳答案

I am not able understand why it (VS Compiler) is not able to find the copy assignment operator which takes void * and gives back MyInsert & when clearly one is explicitly provided.

采用void* 的赋值运算符不是复制 赋值运算符。

编译器确实尝试使用复制赋值运算符,但显然没有明确提供。它也不是隐式提供的,因为有一个引用成员。

输出迭代器必须满足OutputIterator的要求必须满足Iterator的要求必须满足CopyAssignable的要求这毫不奇怪地要求你有一个复制赋值运算符。这是 MyInsert 所缺少的。

why is not able to compile the code which is getting compiled on other major compilers?

虽然输出迭代器必须满足要求,但标准库实现不需要检查是否满足要求。

希望概念的正式规范将来成为标准的一部分,以改进此类情况下的错误消息。

Perhaps a bug?

错误是代码中缺少复制赋值运算符。 VS 和其他编译器在这方面都符合标准。

Current work around that I am using is to remove the reference member in MyInsert class with non-reference member.

通过删除引用成员,您允许隐式声明复制赋值运算符。这就是它起作用的原因。要在保持类型拷贝可分配的同时继续引用对象,请使用普通指针而不是引用。

关于c++ - 删除复制赋值运算符的 VS 2015 Update 3 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39352310/

相关文章:

c++ - QObject 创建 moc 文件,但仍然出现 vtable 错误

C++11 - 将非静态数据成员声明为 'auto'

c++ - 在g++ <7.4.0>上boost::archive::text_iarchive in_archive {is} boost <1.71>崩溃

visual-studio - 查找文件并导航到它的快捷方式不再起作用

c++ - 如何在 Qt 中覆盖 QApplication::notify

c++ - 如何从原始 Ptr 增加共享 Ptr 的计数

c++ - SFML 粒子系统架构

c++ - 如何与特定模板特化成为 friend ?

c# - 如何在没有 Visual Studio 的情况下使用自定义脚本添加/更新引用?

c++ - VS 2015 C++ Redistributable 不在单个 DLL 中?