我有以下代码:

#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]

最佳答案



因为S具有const成员str,该成员使默认的副本分配运算符定义为deleted



不能在operator=上调用const string,这是一个非常量成员函数。

std::vector 的类型要求从C++ 11更改为:



因此,从C++ 11开始,要求取决于您执行的操作。实际上, std::vector::push_back 不需要将T类型设置为CopyAssignableCopyInsertable可以。



这就是为什么它使用gcc4.8.5进行编译,但是gcc4.6.2抱怨复制分配操作符被删除了。 (AFAIK gcc从4.8.1开始支持C++ 11)

10-07 19:25
查看更多