为什么stack <const string>不能用g ++编译?

01d*_*d55 15 c++ templates stl g++

我遇到了这个问题,维护一个大的端口(相对于我们团队的大小)项目,但是创建一个小例子很简单.stackoverflow.cpp:

#include<iostream>
#include<string>
#include<stack>

using namespace std;


int main (int argc, char *argv[]) {
  stack<const string> strstack;
  string str("Hello, world");
  strstack.push(str);
  cout << strstack.top() << endl;
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

看起来没错,对吧?MSVS也这么认为.然而:

g++ stackoverflow.cpp
In file included from /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h:34:0,
                 from /usr/include/c++/4.7/bits/allocator.h:48,
                 from /usr/include/c++/4.7/string:43,
                 from /usr/include/c++/4.7/bits/locale_classes.h:42,
                 from /usr/include/c++/4.7/bits/ios_base.h:43,
                 from /usr/include/c++/4.7/ios:43,
                 from /usr/include/c++/4.7/ostream:40,
                 from /usr/include/c++/4.7/iostream:40,
                 from stackoverflow.cpp:1:
/usr/include/c++/4.7/ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const std::basic_string<char> >’:
/usr/include/c++/4.7/bits/allocator.h:89:11:   required from ‘class std::allocator<const std::basic_string<char> >’
/usr/include/c++/4.7/bits/stl_deque.h:489:61:   required from ‘class std::_Deque_base<const std::basic_string<char>, std::allocator<const std::basic_string<char> > >’
/usr/include/c++/4.7/bits/stl_deque.h:728:11:   required from ‘class std::deque<const std::basic_string<char>, std::allocator<const std::basic_string<char> > >’
/usr/include/c++/4.7/bits/stl_stack.h:98:46:   required from ‘class std::stack<const std::basic_string<char> >’
stackoverflow.cpp:9:23:   required from here
/usr/include/c++/4.7/ext/new_allocator.h:83:7: error: ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const std::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::const_pointer = const std::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::const_reference = const std::basic_string<char>&]’ cannot be overloaded
/usr/include/c++/4.7/ext/new_allocator.h:79:7: error: with ‘_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const std::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::reference = const std::basic_string<char>&]’
/usr/include/c++/4.7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::deallocate(__gnu_cxx::new_allocator<_Tp>::pointer, __gnu_cxx::new_allocator<_Tp>::size_type) [with _Tp = const std::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::size_type = long unsigned int]’:
/usr/include/c++/4.7/bits/stl_deque.h:540:2:   required from ‘void std::_Deque_base<_Tp, _Alloc>::_M_deallocate_node(_Tp*) [with _Tp = const std::basic_string<char>; _Alloc = std::allocator<const std::basic_string<char> >]’
/usr/include/c++/4.7/bits/stl_deque.h:643:2:   required from ‘void std::_Deque_base<_Tp, _Alloc>::_M_destroy_nodes(_Tp**, _Tp**) [with _Tp = const std::basic_string<char>; _Alloc = std::allocator<const std::basic_string<char> >]’
/usr/include/c++/4.7/bits/stl_deque.h:566:4:   required from ‘std::_Deque_base<_Tp, _Alloc>::~_Deque_base() [with _Tp = const std::basic_string<char>; _Alloc = std::allocator<const std::basic_string<char> >]’
/usr/include/c++/4.7/bits/stl_deque.h:781:15:   required from ‘std::deque<_Tp, _Alloc>::deque() [with _Tp = const std::basic_string<char>; _Alloc = std::allocator<const std::basic_string<char> >]’
stackoverflow.cpp:9:23:   required from here
/usr/include/c++/4.7/ext/new_allocator.h:100:9: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
In file included from /usr/include/c++/4.7/ext/new_allocator.h:34:0,
                 from /usr/include/c++/4.7/x86_64-linux-gnu/bits/c++allocator.h:34,
                 from /usr/include/c++/4.7/bits/allocator.h:48,
                 from /usr/include/c++/4.7/string:43,
                 from /usr/include/c++/4.7/bits/locale_classes.h:42,
                 from /usr/include/c++/4.7/bits/ios_base.h:43,
                 from /usr/include/c++/4.7/ios:43,
                 from /usr/include/c++/4.7/ostream:40,
                 from /usr/include/c++/4.7/iostream:40,
                 from stackoverflow.cpp:1:
/usr/include/c++/4.7/new:97:6: error:   initializing argument 1 of ‘void operator delete(void*)’ [-fpermissive]
In file included from /usr/include/c++/4.7/deque:63:0,
                 from /usr/include/c++/4.7/stack:61,
                 from stackoverflow.cpp:3:
/usr/include/c++/4.7/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, const _T2&) [with _T1 = const std::basic_string<char>; _T2 = std::basic_string<char>]’:
/usr/include/c++/4.7/bits/stl_uninitialized.h:77:3:   required from ‘static _ForwardIterator std::__uninitialized_copy<_TrivialValueTypes>::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::_Deque_iterator<const std::basic_string<char>, const std::basic_string<char>&, const std::basic_string<char>*>; _ForwardIterator = std::_Deque_iterator<const std::basic_string<char>, const std::basic_string<char>&, const std::basic_string<char>*>; bool _TrivialValueTypes = false]’
/usr/include/c++/4.7/bits/stl_uninitialized.h:119:41:   required from ‘_ForwardIterator std::uninitialized_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::_Deque_iterator<const std::basic_string<char>, const std::basic_string<char>&, const std::basic_string<char>*>; _ForwardIterator = std::_Deque_iterator<const std::basic_string<char>, const std::basic_string<char>&, const std::basic_string<char>*>]’
/usr/include/c++/4.7/bits/stl_uninitialized.h:260:63:   required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator<_Tp>&) [with _InputIterator = std::_Deque_iterator<const std::basic_string<char>, const std::basic_string<char>&, const std::basic_string<char>*>; _ForwardIterator = std::_Deque_iterator<const std::basic_string<char>, const std::basic_string<char>&, const std::basic_string<char>*>; _Tp = const std::basic_string<char>]’
/usr/include/c++/4.7/bits/stl_deque.h:841:9:   required from ‘std::deque<_Tp, _Alloc>::deque(const std::deque<_Tp, _Alloc>&) [with _Tp = const std::basic_string<char>; _Alloc = std::allocator<const std::basic_string<char> >; std::deque<_Tp, _Alloc> = std::deque<const std::basic_string<char>, std::allocator<const std::basic_string<char> > >]’
/usr/include/c++/4.7/bits/stl_stack.h:130:14:   required from ‘std::stack<_Tp, _Sequence>::stack(const _Sequence&) [with _Tp = const std::basic_string<char>; _Sequence = std::deque<const std::basic_string<char>, std::allocator<const std::basic_string<char> > >]’
stackoverflow.cpp:9:23:   required from here
/usr/include/c++/4.7/bits/stl_construct.h:85:7: error: invalid static_cast from type ‘const std::basic_string<char>*’ to type ‘void*’
Run Code Online (Sandbox Code Playgroud)

有了stack<string> strstack;这一切都干净.这是一个g ++错误吗?是否有一个解决方法,以便我们不必删除,const直到修复错误?

Bo *_*son 26

标准容器的成员必须是可复制的或可移动的(C++ 11).如果类型const不符合要求.

  • 这取决于你在做什么.如果您没有使用容器的所有功能,那么您可能无法满足所有要求.即使允许,也不要求实现失败. (4认同)
  • -1 AFAIK这个答案错了​​.我所知道的容器元素的唯一一般C++ 11要求是它们是可破坏的(并且在C++ 03中不存在移动).请你从标准中引用章节和经文吗? (3认同)
  • @ 01d55:赋值需要可分配项目.*不*意味着"标准容器的成员必须是可复制的或可移动的".这意味着如果您分配给容器,那么它必须具有可分配的项目(并且对于其他操作同上,您实际使用的每个操作都必须是可能的).这个答案是错的,排除了例如`const`项的`std :: list`. (2认同)