VC ++ 2019では、移動専用タイプのemplace_back
(右辺値)list
はできません。
#include <vector>
#include <list>
struct A
{
A(A&&) {}
};
using ListOfA = std::list<A>;
int main()
{
std::vector<ListOfA> v;
// Build error in VC++ 2019
// No error in Clang and GCC C++11 - C++2a
v.emplace_back(std::move(ListOfA()));
}
VC ++ 2019でビルドしようとすると、次のコンパイルエラーが発生します。
'A::A(const A &)': attempting to reference a deleted function
明らかに、VC ++はの(左辺値)コピーコンストラクターをインスタンス化しようとしていますA
が、のコンストラクターの1つを明示的に定義しているため、(正しく)存在しませんA
。
別のクラスから移動list
して、インプレースでインプレースをインスタンス化することは有効であると思います。つまり、クラスには移動コンストラクターがあり、これにより、newが(の要素の所有権を取得するだけでよいと思います。移動元)、コピーを必要としません。vector
list
list
list
list
実際、Wandboxを使用すると、 GCCとClangを使用して同じコードがエラーなしでビルドおよび実行されます。
このコードがVC ++ 2019でコンパイルされない理由を誰かが説明できますか?誤解がありますか?(左辺値の)コピーコンストラクターが上記のコードでVC ++コンパイラーによってインスタンス化されている正当な理由は実際にありますか?
注意
std::move(...)
が存在しない場合、VC ++でも同じエラーが発生します。つまり、次の行でも同じエラーが発生します。
v.emplace_back(ListOfA());
MSVCは、std::list
moveコンストラクターがスローしているため、のコピーコンストラクターを使用します。再割り当て中に、moveコンストラクターがスローした場合std::vector
、標準で要求されている強力な例外保証を提供できません。
あなたの場合、ベクトルには再割り当ての前に要素がないため、コピーコンストラクターが呼び出されていないように見えますが、それはコピーコンストラクターが必要ないという意味ではありません。
std::list
libstdc ++およびlibc ++にはnoexcept
moveコンストラクターがあります。これは許可されていますが、規格では必須ではありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加