デストラクタが宣言されている場合、なぜこのコードはコンパイルされないのですか?

lvella

次のC ++ 11コードについて考えてみます。

#include <thread>
#include <vector>

struct A {
    A() {}

    //virtual ~A() = default;
    //~A() = default;
    //~A() {};

    std::thread t;
};

int main()
{
    std::vector<A> v;
    v.emplace_back();
}

前のコードでデストラクタを宣言している行のいずれかがコメント化されていない場合、このコードはコンパイルされません。コンパイラは、コピーコンストラクタstd::threadが削除されたことについて文句を言いますしかしstd::vector::emplace_back、コピーコンストラクターを使用すべきではないので、なぜ失敗するのでしょうか。そして、なぜデストラクタの言及が重要なのですか?

GCC出力(~A() {};コメントなし):

$ g++ --std=c++11 -o test test.cpp 
In file included from /usr/include/c++/4.8/memory:64:0,
                 from /usr/include/c++/4.8/thread:40,
                 from test.cpp:1:
/usr/include/c++/4.8/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = A; _Args = {A}]’:
/usr/include/c++/4.8/bits/stl_uninitialized.h:75:53:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*; bool _TrivialValueTypes = false]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:117:41:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::move_iterator<A*>; _ForwardIterator = A*; _Tp = A]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:281:69:   required from ‘_ForwardIterator std::__uninitialized_move_if_noexcept_a(_InputIterator, _InputIterator, _ForwardIterator, _Allocator&) [with _InputIterator = A*; _ForwardIterator = A*; _Allocator = std::allocator<A>]’
/usr/include/c++/4.8/bits/vector.tcc:415:43:   required from ‘void std::vector<_Tp, _Alloc>::_M_emplace_back_aux(_Args&& ...) [with _Args = {}; _Tp = A; _Alloc = std::allocator<A>]’
/usr/include/c++/4.8/bits/vector.tcc:101:54:   required from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {}; _Tp = A; _Alloc = std::allocator<A>]’
test.cpp:17:17:   required from here
/usr/include/c++/4.8/bits/stl_construct.h:75:7: error: use of deleted function ‘A::A(const A&)’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
test.cpp:4:8: note: ‘A::A(const A&)’ is implicitly deleted because the default definition would be ill-formed:
 struct A {
        ^
test.cpp:4:8: error: use of deleted function ‘std::thread::thread(const std::thread&)’
In file included from test.cpp:1:0:
/usr/include/c++/4.8/thread:126:5: error: declared here
     thread(const thread&) = delete;
     ^

Clang出力(~A() {};コメントなし):

$ clang++ --std=c++11 -o test test.cpp 
In file included from test.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/memory:64:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_construct.h:75:38: error: 
      call to implicitly-deleted copy constructor of 'A'
    { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
                                     ^   ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:75:8: note: 
      in instantiation of function template specialization
      'std::_Construct<A, A>' requested here
                std::_Construct(std::__addressof(*__cur), *__first);
                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:117:2: note: 
      in instantiation of function template specialization
      'std::__uninitialized_copy<false>::__uninit_copy<std::move_iterator<A *>,
      A *>' requested here
        __uninit_copy(__first, __last, __result);
        ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:258:19: note: 
      in instantiation of function template specialization
      'std::uninitialized_copy<std::move_iterator<A *>, A *>' requested here
    { return std::uninitialized_copy(__first, __last, __result); }
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/stl_uninitialized.h:279:19: note: 
      in instantiation of function template specialization
      'std::__uninitialized_copy_a<std::move_iterator<A *>, A *, A>' requested
      here
      return std::__uninitialized_copy_a
                  ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/vector.tcc:413:15: note: 
      in instantiation of function template specialization
      'std::__uninitialized_move_if_noexcept_a<A *, A *, std::allocator<A> >'
      requested here
              = std::__uninitialized_move_if_noexcept_a
                     ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/bits/vector.tcc:101:4: note: 
      in instantiation of function template specialization 'std::vector<A,
      std::allocator<A> >::_M_emplace_back_aux<>' requested here
          _M_emplace_back_aux(std::forward<_Args>(__args)...);
          ^
test.cpp:17:4: note: in instantiation of function template specialization
      'std::vector<A, std::allocator<A> >::emplace_back<>' requested here
        v.emplace_back();
          ^
test.cpp:11:14: note: copy constructor of 'A' is implicitly deleted because
      field 't' has a deleted copy constructor
        std::thread t;
                    ^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/thread:126:5: note: 
      'thread' has been explicitly marked deleted here
    thread(const thread&) = delete;
    ^
1 error generated.
カール・ニコル

(コメントからの回答、私によるクレジットはありません)

デストラクタが手動で宣言されている場合、コンパイル時にデフォルトの移動コンストラクタは作成されません。デフォルトのmoveコンストラクターを強制的に使用すると、これが修正されます。

A(A&& o) = default;

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

noexcept moveコンストラクターがない場合、std :: vectorを使用したコードはコンパイルされないのに、std :: unique_ptrを使用したコードはコンパイルされるのはなぜですか?

分類Dev

なぜこのコードはコンストラクターについて文句を言わずにコンパイルされるのですか?

分類Dev

変換コンストラクターと変換演算子が定義されている場合、どちらが優先され、コンパイラーがこの変換を異なるのはなぜですか?

分類Dev

このテンプレートクラスがコンパイルされないのはなぜですか?

分類Dev

複数のコンストラクターを使用するこのJavaコードがVSコードで実行されるのに、javacでコンパイルされないのはなぜですか?

分類Dev

保護されたC ++-Cliデストラクタがコンパイルエラーを引き起こさないのはなぜですか?

分類Dev

別の構造体がメンバーとして共用体にラップされている構造体が、明示的なデフォルトコンストラクターなしでコンパイルされないのはなぜですか?

分類Dev

コンストラクタープロパティがオーバーライドされていない場合、オブジェクトのコンストラクタープロパティがextend関数でFではなく親のコンストラクターを指すのはなぜですか

分類Dev

インスタンスメソッドが静的コンテキストで使用されている場合、javacが「エラー:クラスのメソッドを特定のタイプに適用できない」と出力するのはなぜですか?

分類Dev

他のクラスにバインドされている場合でも、未定義のGenericsタイプのコレクションがデフォルトでObjectになるのはなぜですか?

分類Dev

データ型に演算子<が定義されていないのに、std :: mapコードがコンパイルされるのはなぜですか?

分類Dev

このコードがEclipseコンパイラでコンパイルされ、javac(maven)ではコンパイルされないのはなぜですか

分類Dev

このコードがコンパイルされているのはなぜですか?

分類Dev

メインの前に関数が宣言されていなくても、このオンラインコンパイラでコードをコンパイルできるのはなぜですか?

分類Dev

追加のテンプレート引数を宣言し、定義で使用されていない場合、コンパイラがエラーをスローするのはなぜですか?

分類Dev

コピーコンストラクター/ oper =のみを定義した場合、ムーブコンストラクター/ムーブ代入が暗黙的に宣言および削除済みとして定義されないのはなぜですか?

分類Dev

Typescript:プロパティ値がネストされたオブジェクトからのものである場合、コードがコンパイルされないのはなぜですか?

分類Dev

この場合、最も適切なコンストラクターが呼び出されないのはなぜですか?

分類Dev

このCコードがCodeblocksでコンパイルされるのに、Visual Studioではコンパイルされないのはなぜですか?

分類Dev

このコードが日食でコンパイルされるのにjGraspではコンパイルされないのはなぜですか

分類Dev

コンストラクターで、スーパークラスコンストラクターが実行される前に、現在のクラスのフィールドが参照されないのはなぜですか?

分類Dev

Typescriptがトランスパイルされたコードのクラスコンストラクターに.default()を追加するのはなぜですか?

分類Dev

この少ないコードがコンパイルされないのはなぜですか?

分類Dev

Haskellの型ではなく、値コンストラクターで型が宣言されているのはなぜですか?

分類Dev

C ++ 17で移動/コピーコンストラクタ/代入が「削除」または「宣言されていない」場合に確立されていますか?

分類Dev

パラメータが「const」とマークされている場合でも、コピーコンストラクタが呼び出されるのはなぜですか?

分類Dev

演算子のオーバーロードでコンストラクターを返すことが許可されているのはなぜですか?

分類Dev

このプロパティがディレクティブのスコープにバインドされていないのはなぜですか?

分類Dev

オブジェクトをパラメーターとして渡すときに、デストラクタが呼び出されているのにコンストラクションが呼び出されていないのはなぜですか?

Related 関連記事

  1. 1

    noexcept moveコンストラクターがない場合、std :: vectorを使用したコードはコンパイルされないのに、std :: unique_ptrを使用したコードはコンパイルされるのはなぜですか?

  2. 2

    なぜこのコードはコンストラクターについて文句を言わずにコンパイルされるのですか?

  3. 3

    変換コンストラクターと変換演算子が定義されている場合、どちらが優先され、コンパイラーがこの変換を異なるのはなぜですか?

  4. 4

    このテンプレートクラスがコンパイルされないのはなぜですか?

  5. 5

    複数のコンストラクターを使用するこのJavaコードがVSコードで実行されるのに、javacでコンパイルされないのはなぜですか?

  6. 6

    保護されたC ++-Cliデストラクタがコンパイルエラーを引き起こさないのはなぜですか?

  7. 7

    別の構造体がメンバーとして共用体にラップされている構造体が、明示的なデフォルトコンストラクターなしでコンパイルされないのはなぜですか?

  8. 8

    コンストラクタープロパティがオーバーライドされていない場合、オブジェクトのコンストラクタープロパティがextend関数でFではなく親のコンストラクターを指すのはなぜですか

  9. 9

    インスタンスメソッドが静的コンテキストで使用されている場合、javacが「エラー:クラスのメソッドを特定のタイプに適用できない」と出力するのはなぜですか?

  10. 10

    他のクラスにバインドされている場合でも、未定義のGenericsタイプのコレクションがデフォルトでObjectになるのはなぜですか?

  11. 11

    データ型に演算子<が定義されていないのに、std :: mapコードがコンパイルされるのはなぜですか?

  12. 12

    このコードがEclipseコンパイラでコンパイルされ、javac(maven)ではコンパイルされないのはなぜですか

  13. 13

    このコードがコンパイルされているのはなぜですか?

  14. 14

    メインの前に関数が宣言されていなくても、このオンラインコンパイラでコードをコンパイルできるのはなぜですか?

  15. 15

    追加のテンプレート引数を宣言し、定義で使用されていない場合、コンパイラがエラーをスローするのはなぜですか?

  16. 16

    コピーコンストラクター/ oper =のみを定義した場合、ムーブコンストラクター/ムーブ代入が暗黙的に宣言および削除済みとして定義されないのはなぜですか?

  17. 17

    Typescript:プロパティ値がネストされたオブジェクトからのものである場合、コードがコンパイルされないのはなぜですか?

  18. 18

    この場合、最も適切なコンストラクターが呼び出されないのはなぜですか?

  19. 19

    このCコードがCodeblocksでコンパイルされるのに、Visual Studioではコンパイルされないのはなぜですか?

  20. 20

    このコードが日食でコンパイルされるのにjGraspではコンパイルされないのはなぜですか

  21. 21

    コンストラクターで、スーパークラスコンストラクターが実行される前に、現在のクラスのフィールドが参照されないのはなぜですか?

  22. 22

    Typescriptがトランスパイルされたコードのクラスコンストラクターに.default()を追加するのはなぜですか?

  23. 23

    この少ないコードがコンパイルされないのはなぜですか?

  24. 24

    Haskellの型ではなく、値コンストラクターで型が宣言されているのはなぜですか?

  25. 25

    C ++ 17で移動/コピーコンストラクタ/代入が「削除」または「宣言されていない」場合に確立されていますか?

  26. 26

    パラメータが「const」とマークされている場合でも、コピーコンストラクタが呼び出されるのはなぜですか?

  27. 27

    演算子のオーバーロードでコンストラクターを返すことが許可されているのはなぜですか?

  28. 28

    このプロパティがディレクティブのスコープにバインドされていないのはなぜですか?

  29. 29

    オブジェクトをパラメーターとして渡すときに、デストラクタが呼び出されているのにコンストラクションが呼び出されていないのはなぜですか?

ホットタグ

アーカイブ