2016-09-06 7 views
4

次のコードは、clang-3.8とgcc 4.9.3でうまくコンパイルされます。削除されたコピー代入演算子のVS 2015 Update 3エラー

ただし、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 *を取り、明確に1が明示的に提供されたときに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と入力され、に入ります0ヘッダ。

このアサインでは、コピー代入演算子が呼び出され(MyInsert&として入力され、出力がMyInsert&)、見つからないため、attempting to reference...というエラーメッセージが表示されます。

この分析は正しいですか?そうでなければ、なぜ他のメジャーなコンパイラでコンパイルされているコードをコンパイルできないのですか?おそらくバグでしょうか?私が使っていることを

P.S

現在の仕事の周りには、非基準部材とMyInsertクラスの参照メンバーを削除することです。

+0

@Oktalistああ、私の悪い! – Yakk

答えて

5

私はできないですが、それ(VSコンパイラは)void *を取り、明確に1が明示的に提供されたときにMyInsert &をバック与えコピー代入演算子を見つけることができない理由を理解しています。

void*を取る代入演算子はコピー代入演算子はありません。

コンパイラは、明確にでないコピー代入演算子を明示的に使用しようとします。参照メンバが存在するため、暗黙的にも提供されません。

出力イテレータは当然コピー代入演算子を持っているあなたを必要とCopyAssignableの要件を満たしている必要がありIteratorの要件を満たしている必要がありOutputIteratorの要件を満たす必要があります。これは、MyInsertが欠けているものです。

なぜ他のメジャーコンパイラでコンパイルされているコードをコンパイルできないのですか?

出力イテレータは要件を満たす必要がありますが、標準ライブラリ実装で要件が満たされているかどうかを確認する必要はありません。

今後、このような場合にエラーメッセージを改善するために、概念の正式な仕様が標準の一部となることを望みます。

おそらくバグですか?

コードに不足しているコピー代入演算子がバグです。この点に関して、VSと他のコンパイラの両方が標準に準拠しています。

私が使用している現在の回避策は、非参照メンバでMyInsertクラスの参照メンバを削除することです。

参照メンバーを削除することにより、コピー代入演算子の暗黙の宣言を許可します。そういうわけで、それは機能します。型コピーを代入したままでオブジェクトを参照し続けるには、参照の代わりにプレーンポインタを使用します。

+0

@NathanOliver私はそれが奇妙ではありません。出力イテレータをコピーする必要のない 'std :: transform'の実装を想像するのは簡単です。 'std :: transform'を呼び出すとエラーになります:それがうまくいくという保証はありませんが、標準で実装がタイプ要件が満たされているかどうかを確認する必要はないと思います。 – user2079303

+0

ええ、私はそれを実現しました。私が持っている問題は、コピーコンストラクタも削除する必要がありますので、もし私たちがコピーの削除を止めれば、それがどのように関数を呼び出すのか分かりません。 – NathanOliver

+0

[this](http://coliru.stacked-crooked.com/a/3051bb080f39558e)が失敗するはずですが、そうでないと私は同意します。 – NathanOliver

関連する問題