2016-06-22 1 views
2

私は次のコードを持っている:生成された演算子のシグネチャ=()?

#include <string> 
#include <vector> 

struct S { 
    const std::string str; 
}; 

int main() { 
    std::vector<S> v; 
    const std::string test("test"); 
    S s; 
    v.push_back(s); 
} 

をそれをg ++ 4.8.5と罰金コンパイル:

$ g++ --version 
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-4) 
Copyright (C) 2015 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

しかし、私はG ++ 4.6.2でコンパイルしようとしたとき、私は次のエラーを得ました:

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:70:0, 
       from compilerTest.cpp:2: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const S&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:834:4: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::value_type = S]’ 
compilerTest.cpp:12:14: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: error: use of deleted function ‘S& S::operator=(const S&)’ 
compilerTest.cpp:4:8: error: ‘S& S::operator=(const S&)’ is implicitly deleted because the default definition would be ill-formed: 
compilerTest.cpp:4:8: error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]’ discards qualifiers [-fpermissive] 
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/char_traits.h:41:0, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/string:42, 
       from compilerTest.cpp:1: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:581:18: instantiated from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:590:34: instantiated from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:661:15: instantiated from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:313:4: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {const S&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_vector.h:834:4: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const value_type&) [with _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::value_type = S]’ 
compilerTest.cpp:12:14: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:546:6: error: use of deleted function ‘S& S::operator=(const S&)’ 

なぜS& S::operator=(const S&)が「削除されましたか」

私はコンパイルするコマンドを使用していた。

g++ -Wall compilerTest.cpp -o compilerTest -std=c++0x 

はさえ、私は(emplace_backを使用しています)、それは私に同様のエラーを与える:あなたは非静的を持っているとき

In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/x86_64-redhat-linux/bits/c++allocator.h:34:0, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/allocator.h:48, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/string:43, 
       from compilerTest.cpp:1: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/new_allocator.h: In member function ‘void __gnu_cxx::new_allocator<_Tp>::construct(__gnu_cxx::new_allocator<_Tp>::pointer, _Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, __gnu_cxx::new_allocator<_Tp>::pointer = S*]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:97:6: instantiated from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>]’ 
compilerTest.cpp:11:18: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/new_allocator.h:114:4: error: no matching function for call to ‘S::S(std::basic_string<char>&)’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/ext/new_allocator.h:114:4: note: candidates are: 
compilerTest.cpp:4:8: note: S::S() 
compilerTest.cpp:4:8: note: candidate expects 0 arguments, 1 provided 
compilerTest.cpp:4:8: note: S::S(const S&) 
compilerTest.cpp:4:8: note: no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘const S&’ 
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/vector:70:0, 
       from compilerTest.cpp:2: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc: In member function ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>]’ 
compilerTest.cpp:11:18: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: error: no matching function for call to ‘S::S(std::basic_string<char>&)’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:319:4: note: candidates are: 
compilerTest.cpp:4:8: note: S::S() 
compilerTest.cpp:4:8: note: candidate expects 0 arguments, 1 provided 
compilerTest.cpp:4:8: note: S::S(const S&) 
compilerTest.cpp:4:8: note: no known conversion for argument 1 from ‘std::basic_string<char>’ to ‘const S&’ 
In file included from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/char_traits.h:41:0, 
       from /usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/string:42, 
       from compilerTest.cpp:1: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h: In static member function ‘static _BI2 std::__copy_move_backward<true, false, std::random_access_iterator_tag>::__copy_move_b(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’: 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:581:18: instantiated from ‘_BI2 std::__copy_move_backward_a(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:590:34: instantiated from ‘_BI2 std::__copy_move_backward_a2(_BI1, _BI1, _BI2) [with bool _IsMove = true, _BI1 = S*, _BI2 = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:661:15: instantiated from ‘_BI2 std::move_backward(_BI1, _BI1, _BI2) [with _BI1 = S*, _BI2 = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:313:4: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(std::vector<_Tp, _Alloc>::iterator, _Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>, std::vector<_Tp, _Alloc>::iterator = __gnu_cxx::__normal_iterator<S*, std::vector<S> >, typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer = S*]’ 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/vector.tcc:102:4: instantiated from ‘void std::vector<_Tp, _Alloc>::emplace_back(_Args&& ...) [with _Args = {std::basic_string<char>&}, _Tp = S, _Alloc = std::allocator<S>]’ 
compilerTest.cpp:11:18: instantiated from here 
/usr/lib/gcc/x86_64-redhat-linux/4.6.2/../../../../include/c++/4.6.2/bits/stl_algobase.h:546:6: error: use of deleted function ‘S& S::operator=(const S&)’ 
compilerTest.cpp:4:8: error: ‘S& S::operator=(const S&)’ is implicitly deleted because the default definition would be ill-formed: 
compilerTest.cpp:4:8: error: passing ‘const string {aka const std::basic_string<char>}’ as ‘this’ argument of ‘std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>, std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>]’ discards qualifiers [-fpermissive] 
+2

push_backがコピー代入を使用するのは非常に面白いです。emplace_back() – gbehar

+0

@gbehar同じエラーです。私は、要素が挿入されたときにstdコンテナがコピーを作成するので、push_back()が代入演算子を呼び出すことが知られていると思います。 – Hei

+0

実際には、暗黙のコピーコンストラクタがあり、C++ 11ではpush_backが使用するものがあります。私は-std = C++ 0xでもこれを完全にサポートしていないと思います。 C++ 03では、ベクトル項目にコピーコンストラクタとコピー代入の両方が必要です。あなたのケースでは、コピーの割り当てが削除されました – gbehar

答えて

4

Why S& S::operator=(const S&) is "deleted"?

を持つように、ベクトルメンバーを必要とC++ 11のフルサポートがありません。

A defaulted copy assignment operator for class T is defined as deleted if any of the following is true:

T has a non-static data member or a direct or virtual base class that cannot be copy-assigned (overload resolution for the copy assignment fails, or selects a deleted or inaccessible function);

それは非constメンバ関数だ、const stringoperator=を呼び出すことは不可能です。

そして、C++ 11から変更std::vectorの種類要件:

T must meet the requirements of CopyAssignable and CopyConstructible. (until C++11)

The requirements that are imposed on the elements depend on the actual operations performed on the container. Generally, it is required that element type is a complete type and meets the requirements of Erasable, but many member functions impose stricter requirements. (since C++11)

だから、C++ 11からのrequirmentは、あなたが行った操作に依存します。実際には、std::vector::push_backは、タイプTCopyAssignableである必要はありません。CopyInsertableは問題ありません。

Type requirements
- T must meet the requirements of CopyInsertable in order to use overload (1).

だからgcc4.8.5でコンパイルされますが、gcc4.6.2はコピー代入演算子が削除されるという不満があります。 (AFAIK gccは4.8.1からC++ 11をサポートしました)

+0

非常に詳細な答え。私は、CopyInsertableについてもっと冗長な記述があるかどうか疑問に思いますか?あなたが含まれているリンクは、それが意味することについて正式な説明を提供します。しかし、 "std :: allocator_traits :: construct(m、p、v);"を見て少し難しい;単語の形のよい手段である(表現がエラーなしにコンパイルできることに加えて)。ありがとう。 – Hei

+0

@Heiポイントは(冒頭にも書かれています) "コピー可能です"。あなたのケースでは、:: new((void *)p)T(v) "のように(最後にも書かれています)" 'S'はconstメンバーを持ち、' ​​operator =() 'でコピーを割り当てることはできませんが、コピーコンストラクタによって作成されたコピーである可能性があります。それは違いです。 – songyuanyao

+0

constメンバーがoperator =()によって代入されないというあなたの要点を見ています。あなたは私にコピーを作れないものの例を教えてもらえますか? (私はこれが元のポストから少しずれていることを知っています;あなたが気にしないことを願っています)ありがとう。 – Hei

2

コピーの割り当てが暗黙のうちに削除されますconstメンバー

これは、コピー先のオブジェクトが再初期化されていないため、再割り当てできない既存のconstがあるためです。

あなたのケースではSが不履行コピー代入演算子を作るconstメンバーstrdeletedのように定義されているのでコピー代入

関連する問題