I'm using a class called Buffer which has the following operator:
unsigned char &operator[](size_t index)
I'm trying to copy from it like this:
std::copy(buf[96], buf[96 + 32], my_uint32_t);
I think it doesn't work
/usr/include/c++/7/bits/stl_algobase.h: In instantiation of '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned char; _OI = unsigned int]':
/usr/include/c++/7/bits/stl_algobase.h:422:45: required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = unsigned char; _OI = unsigned int]'
/usr/include/c++/7/bits/stl_algobase.h:455:8: required from '_OI std::copy(_II, _II, _OI) [with _II = unsigned char; _OI = unsigned int]'
/home/project/SimplePacketCrafter.h:36:95: required from here
/usr/include/c++/7/bits/stl_algobase.h:377:57: error: no type named 'value_type' in 'struct std::iterator_traits<unsigned char>'
typedef typename iterator_traits<_II>::value_type _ValueTypeI;
^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:378:57: error: no type named 'value_type' in 'struct std::iterator_traits<unsigned int>'
typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
^~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:379:64: error: no type named 'iterator_category' in 'struct std::iterator_traits<unsigned char>'
typedef typename iterator_traits<_II>::iterator_category _Category;
^~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:383:9: error: no type named 'value_type' in 'struct std::iterator_traits<unsigned char>'
const bool __simple = (__is_trivial(_ValueTypeI)
~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __is_pointer<_II>::__value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __is_pointer<_OI>::__value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __are_same<_ValueTypeI, _ValueTypeO>::__value);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/c++/7/bits/stl_algobase.h:386:44: error: no type named 'iterator_category' in 'struct std::iterator_traits<unsigned char>'
return std::__copy_move<_IsMove, __simple,
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
_Category>::__copy_m(__first, __last, __result);
because I think I'm supposed to pass an address in the first two. There's also
unsigned char *index(size_t index)
but it also doesn't work
The methods can be seen here
std:copy() takes iterators, not references. That is why you are getting an error.
Raw pointers can be used as iterators, provided the elements being pointed to are stored sequentially in memory. So, assuming the buffer's operator[] returns a reference to elements in a single memory buffer, you can use the & address operator to get the memory addresses of the chars being referred to by operator[], and then std::copy() can iterate between those two addresses:
std::copy(&buf[96], &buf[96 + 32], my_uint32_t);
Alternatively, the buffer's index() and c_index() methods return equivilent pointers:
std::copy(buf.index(96), buf.index(96 + 32), my_uint32_t);
std::copy(buf.c_index(96), buf.c_index(96 + 32), my_uint32_t);
Related
I am trying to remove the first value of a vector of template typenames. Using the erase() method in vector stl, I keep getting this error:
TTrie.inc:56:19: error: passing ‘const std::vector<char, std::allocator<char> >’ as ‘this’ argument discards qualifiers [-fpermissive]
56 | sequence.erase(it);
| ~~~~~~~~~~~~~~^~~~
In file included from /usr/include/c++/10/vector:67,
from TTrie.h:5,
from TTrieTest.cpp:1:
/usr/include/c++/10/bits/stl_vector.h:1430:7: note: in call to ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::const_iterator) [with _Tp = char; _Alloc = std::allocator<char>; std::vector<_Tp, _Alloc>::iterator = std::vector<char, std::allocator<char> >::iterator; std::vector<_Tp, _Alloc>::const_iterator = std::vector<char, std::allocator<char> >::const_iterator]’
1430 | erase(const_iterator __position)
| ^~~~~
In file included from TTrie.h:115,
from TTrieTest.cpp:1:
TTrie.inc: In instantiation of ‘TTrie<DataType>& TTrie<DataType>::operator+=(const std::vector<DataType>&) [with DataType = std::__cxx11::basic_string<char>]’:
TTrieTest.cpp:93:10: required from here
TTrie.inc:56:19: error: passing ‘const std::vector<std::__cxx11::basic_string<char> >’ as ‘this’ argument discards qualifiers [-fpermissive]
56 | sequence.erase(it);
| ~~~~~~~~~~~~~~^~~~
In file included from /usr/include/c++/10/vector:67,
from TTrie.h:5,
from TTrieTest.cpp:1:
/usr/include/c++/10/bits/stl_vector.h:1430:7: note: in call to ‘std::vector<_Tp, _Alloc>::iterator std::vector<_Tp, _Alloc>::erase(std::vector<_Tp, _Alloc>::const_iterator) [with _Tp = std::__cxx11::basic_string<char>; _Alloc = std::allocator<std::__cxx11::basic_string<char> >; std::vector<_Tp, _Alloc>::iterator = std::vector<std::__cxx11::basic_string<char> >::iterator; std::vector<_Tp, _Alloc>::const_iterator = std::vector<std::__cxx11::basic_string<char> >::const_iterator]’
1430 | erase(const_iterator __position)
| ^~~~~
In file included from TTrie.h:115,
from TTrieTest.cpp:1:
Is it having trouble because sequence should be const? Am I declaring the iterator wrong somehow? Here is my code. Please let me know If you have any questions:
template<typename DataType>
TTrie<DataType>& TTrie<DataType>::operator+=(const std::vector<DataType>& sequence) {
const DataType c = sequence[0];
const TTrie<DataType>* child = getChild(c); //Returns a pointer to a child node or a nullptr
if (!child) {
TTrie<DataType>* n = new TTrie<DataType>(c);
edgeMap[c] = n;
}
if(sequence.size() > 1) {
typename std::vector<DataType>::const_iterator it;
it = sequence.cbegin(); //First value of sequence
sequence.erase(it);
*edgeMap[c] += sequence;
}
return *this;
}
Your sequence parameter is a reference to a const std::vector<DataType> object. But std::vector::erase() is not qualified as being a const method, as it modifies the content of the vector, so it cannot be called on a const object. That is what the error message is trying to tell you - that erase() is being called on a const object.
This code compiles if the std::copy is commented out, and the atc initializer is uncommented.
class MyClass {
MyClass( OtherClass* poc_in, std::initializer_list<ThirdClass> iltc) :
poc( poc_in)
//, atc(iltc)
{
std::copy( iltc.begin(), iltc.end(), atc );
}
OtherClass* poc;
std::vector<ThirdClass> atc;
}
However, as written I get:
In file included from /opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/algorithm:61:0,
from ../../../src/tester/main.cpp:5:
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h: In instantiation of '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = const ThirdClass*; _OI = std::vector<ThirdClass>]':
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:422:45: required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = const ThirdClass*; _OI = std::vector<ThirdClass>]'
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:455:8: required from '_OI std::copy(_II, _II, _OI) [with _II = const ThirdClass*; _OI = std::vector<ThirdClass>]'
../../../src/tester/main.cpp:75:59: required from here
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:378:57: error: no type named 'value_type' in 'struct std::iterator_traits<std::vector<ThirdClass> >'
typedef typename iterator_traits<_OI>::value_type _ValueTypeO;
^~~~~~~~~~~
/opt/rh/devtoolset-6/root/usr/include/c++/6.3.1/bits/stl_algobase.h:383:9: error: no type named 'value_type' in 'struct std::iterator_traits<std::vector<ThirdClass> >'
const bool __simple = (__is_trivial(_ValueTypeI)
~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __is_pointer<_II>::__value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __is_pointer<_OI>::__value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
&& __are_same<_ValueTypeI, _ValueTypeO>::__value);
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
I've read a half-dozen similar questions on Stack Overflow but none sheds light on why this version is unloved. Any suggestions?
This has nothing to do with initialiser lists.
You're using std::copy wrong.
That third argument should be an output iterator, not a vector.
Try using std::back_inserter:
std::copy( iltc.begin(), iltc.end(), std::back_inserter(atc) );
The compilation error is admittedly a little esoteric, but it's saying that the compiler is looking for the member value_type (which all most iterators have) in the traits helper for the type of the argument you gave it (a vector), which doesn't exist (because a vector isn't an iterator).
I know there are already several topics related to overloading the copy and assignment operators of base classes - but after two days of trying, I wasn't able to properly do this using boost::filesystem::path.
What I currently have:
using namespace boost::filesystem;
class MyPath: public path
{
public:
template<class C>
MyPath(const C* p): path(p)// dispatch to base copy constructor
{
//http://stackoverflow.com/questions/1226634/how-to-use-base-classs-constructors-and-assignment-operator-in-c
//this one seems to be OK
}
MyPath& operator=(const MyPath& p)
{
path::operator=(p);
return *this;
}
bool myStuff(){/*...*/}
/* ... */
}
Then, I use the MyPath class just like 'path' before:
using namespace std;
using namespace boost::filesystem;
list<MyPath> files_list;
MyPath input_folder("a valid path");
copy(recursive_directory_iterator(input_folder), recursive_directory_iterator(), back_inserter(files_list));
This code works OK with path, but with MyPath I have problems with the assignment operator, and I haven't figured out how yet what is the format of the operator= that it's required by the std::list and the iterators..
g++ -g -Ic:/mingw/include -c main.cpp
In file included from c:\mingw\include\c++\4.8.1\bits\char_traits.h:39:0,
from c:\mingw\include\c++\4.8.1\ios:40,
from c:\mingw\include\c++\4.8.1\ostream:38,
from c:\mingw\include\c++\4.8.1\iostream:39,
from main.cpp:1:
c:\mingw\include\c++\4.8.1\bits\stl_algobase.h: In instantiation of 'static _OI std::__copy_move<<anonymous>, <anonymous>, <template-parameter-1-3> >::__copy_m(_II, _II, _OI) [with _II = boost::filesystem::recursive_directory_iterator; _OI = std::back_insert_iterator<std::list<MyPath> >; bool <anonymous> = false; bool <anonymous> = false; <template-parameter-1-3> = std::input_iterator_tag]':
c:\mingw\include\c++\4.8.1\bits\stl_algobase.h:390:70: required from '_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = false; _II = boost::filesystem::recursive_directory_iterator; _OI = std::back_insert_iterator<std::list<MyPath> >]'
c:\mingw\include\c++\4.8.1\bits\stl_algobase.h:428:38: required from '_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = false; _II = boost::filesystem::recursive_directory_iterator; _OI = std::back_insert_iterator<std::list<MyPath> >]'
c:\mingw\include\c++\4.8.1\bits\stl_algobase.h:460:17: required from '_OI std::copy(_II, _II, _OI) [with _II = boost::filesystem::recursive_directory_iterator; _OI = std::back_insert_iterator<std::list< MyPath> >]'
main.cpp:23:115: required from here
c:\mingw\include\c++\4.8.1\bits\stl_algobase.h:305:16: error: no match for 'operator=' (operand types are 'std::back_insert_iterator<std::list<MyPath> >' and 'boost::filesystem::directory_entry')
*__result = *__first;
^
c:\mingw\include\c++\4.8.1\bits\stl_algobase.h:305:16: note: candidates are:
In file included from c:\mingw\include\c++\4.8.1\bits\stl_algobase.h:67:0,
from c:\mingw\include\c++\4.8.1\bits\char_traits.h:39,
from c:\mingw\include\c++\4.8.1\ios:40,
from c:\mingw\include\c++\4.8.1\ostream:38,
from c:\mingw\include\c++\4.8.1\iostream:39,
from main.cpp:1:
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:436:7: note: std::back_insert_iterator<_Container>& std::back_insert_iterator<_Container>::operator=(const typename _Container::value_type&) [with _Container = std::list<MyPath>; typename _Container::value_type = MyPath]
operator=(const typename _Container::value_type& __value)
^
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:436:7: note: no known conversion for argument 1 from 'boost::filesystem::directory_entry' to 'const value_type& {aka const MyPath&}'
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:443:7: note: std::back_insert_iterator<_Container>& std::back_insert_iterator<_Container>::operator=(typename _Container::value_type&&) [with _Container = std::list<MyPath>; typename _Container::value_type = MyPath]
operator=(typename _Container::value_type&& __value)
^
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:443:7: note: no known conversion for argument 1 from 'boost::filesystem::directory_entry' to 'std::list<MyPath>::value_type&& {aka MyPath&&}'
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:402:11: note: std::back_insert_iterator<std::list<MyPath> >& std::back_insert_iterator<std::list<MyPath> >::operator=(const std::back_insert_iterator<std::list< MyPath> >&)
class back_insert_iterator
^
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:402:11: note: no known conversion for argument 1 from 'boost::filesystem::directory_entry' to 'const std::back_insert_iterator<std::list<MyPath> >&'
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:402:11: note: std::back_insert_iterator<std::list<MyPath> >& std::back_insert_iterator<std::list<MyPath> >::operator=(std::back_insert_iterator<std::list<MyPath> >&&)
c:\mingw\include\c++\4.8.1\bits\stl_iterator.h:402:11: note: no known conversion for argument 1 from 'boost::filesystem::directory_entry' to 'std::back_insert_iterator<std::list<MyPath> >&&'
make: *** [main.o] Error 1
The compiler is telling you what you need:
'operator=' (operand types are 'std::back_insert_iterator<std::list<MyPath> >' and 'boost::filesystem::directory_entry')
So you need to implement one more method (at least).
This question already has answers here:
Why does stack<const string> not compile in g++? [duplicate]
(2 answers)
Closed 9 years ago.
I have been told that it is good practice to call vector.reserve() before inserting a large amount of elements. I just came upon a situation where I want to put a large number of const elements into a vector. When calling reserve(), however, a compiler error is thrown.
Consider the following code reproducing the problem:
#include <vector>
int main()
{
std::vector<const int> vec;
vec.reserve(2);
}
This results in the following huge compiler error:
In file included from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h:33:0,
from /usr/include/c++/4.8/bits/allocator.h:46,
from /usr/include/c++/4.8/vector:61,
from vecreserve.cpp:1:
/usr/include/c++/4.8/ext/new_allocator.h: In instantiation of ‘struct __gnu_cxx::new_allocator’:
/usr/include/c++/4.8/bits/allocator.h:92:11: required from ‘class std::allocator’
/usr/include/c++/4.8/bits/alloc_traits.h:90:43: required from ‘struct std::allocator_traits >’
/usr/include/c++/4.8/ext/alloc_traits.h:121:10: required from ‘struct __gnu_cxx::__alloc_traits >’
/usr/include/c++/4.8/bits/stl_vector.h:75:28: required from ‘struct std::_Vector_base >’
/usr/include/c++/4.8/bits/stl_vector.h:210:11: required from ‘class std::vector’
vecreserve.cpp:5:26: required from here
/usr/include/c++/4.8/ext/new_allocator.h:93:7: error: ‘const _Tp* __gnu_cxx::new_allocator::address(__gnu_cxx::new_allocator::const_reference) const [with _Tp = const int; __gnu_cxx::new_allocator::const_pointer = const int*; __gnu_cxx::new_allocator::const_reference = const int&]’ cannot be overloaded
address(const_reference __x) const _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.8/ext/new_allocator.h:89:7: error: with ‘_Tp* __gnu_cxx::new_allocator::address(__gnu_cxx::new_allocator::reference) const [with _Tp = const int; __gnu_cxx::new_allocator::pointer = const int*; __gnu_cxx::new_allocator::reference = const int&]’
address(reference __x) const _GLIBCXX_NOEXCEPT
^
/usr/include/c++/4.8/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator::deallocate(__gnu_cxx::new_allocator::pointer, __gnu_cxx::new_allocator::size_type) [with _Tp = const int; __gnu_cxx::new_allocator::pointer = const int*; __gnu_cxx::new_allocator::size_type = long unsigned int]’:
/usr/include/c++/4.8/bits/stl_vector.h:174:4: required from ‘void std::_Vector_base::_M_deallocate(std::_Vector_base::pointer, std::size_t) [with _Tp = const int; _Alloc = std::allocator; std::_Vector_base::pointer = const int*; std::size_t = long unsigned int]’
/usr/include/c++/4.8/bits/vector.tcc:80:28: required from ‘void std::vector::reserve(std::vector::size_type) [with _Tp = const int; _Alloc = std::allocator; std::vector::size_type = long unsigned int]’
vecreserve.cpp:6:16: required from here
/usr/include/c++/4.8/ext/new_allocator.h:110:30: error: invalid conversion from ‘const void*’ to ‘void*’ [-fpermissive]
{ ::operator delete(__p); }
^
In file included from /usr/include/c++/4.8/ext/new_allocator.h:33:0,
from /usr/include/x86_64-linux-gnu/c++/4.8/bits/c++allocator.h:33,
from /usr/include/c++/4.8/bits/allocator.h:46,
from /usr/include/c++/4.8/vector:61,
from vecreserve.cpp:1:
/usr/include/c++/4.8/new:95:6: error: initializing argument 1 of ‘void operator delete(void*)’ [-fpermissive]
void operator delete(void*) _GLIBCXX_USE_NOEXCEPT
^
In file included from /usr/include/c++/4.8/vector:60:0,
from vecreserve.cpp:1:
/usr/include/c++/4.8/bits/stl_algobase.h: In instantiation of ‘_OI std::__copy_move_a(_II, _II, _OI) [with bool _IsMove = true; _II = const int*; _OI = const int*]’:
/usr/include/c++/4.8/bits/stl_algobase.h:428:38: required from ‘_OI std::__copy_move_a2(_II, _II, _OI) [with bool _IsMove = true; _II = const int*; _OI = const int*]’
/usr/include/c++/4.8/bits/stl_algobase.h:460:17: required from ‘_OI std::copy(_II, _II, _OI) [with _II = std::move_iterator; _OI = const int*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:93:53: required from ‘static _ForwardIterator std::__uninitialized_copy::__uninit_copy(_InputIterator, _InputIterator, _ForwardIterator) [with _InputIterator = std::move_iterator; _ForwardIterator = const int*]’
/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; _ForwardIterator = const int*]’
/usr/include/c++/4.8/bits/stl_uninitialized.h:258:63: required from ‘_ForwardIterator std::__uninitialized_copy_a(_InputIterator, _InputIterator, _ForwardIterator, std::allocator&) [with _InputIterator = std::move_iterator; _ForwardIterator = const int*; _Tp = const int]’
/usr/include/c++/4.8/bits/stl_vector.h:1142:29: required from ‘std::vector::pointer std::vector::_M_allocate_and_copy(std::vector::size_type, _ForwardIterator, _ForwardIterator) [with _ForwardIterator = std::move_iterator; _Tp = const int; _Alloc = std::allocator; std::vector::pointer = const int*; std::vector::size_type = long unsigned int]’
/usr/include/c++/4.8/bits/vector.tcc:75:70: required from ‘void std::vector::reserve(std::vector::size_type) [with _Tp = const int; _Alloc = std::allocator; std::vector::size_type = long unsigned int]’
vecreserve.cpp:6:16: required from here
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: error: no matching function for call to ‘std::__copy_move::__copy_m(const int*&, const int*&, const int*&)’
_Category>::__copy_m(__first, __last, __result);
^
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: note: candidate is:
/usr/include/c++/4.8/bits/stl_algobase.h:368:9: note: template static _Tp* std::__copy_move::__copy_m(const _Tp*, const _Tp*, _Tp*) [with _Tp = _Tp; bool _IsMove = true]
__copy_m(const _Tp* __first, const _Tp* __last, _Tp* __result)
^
/usr/include/c++/4.8/bits/stl_algobase.h:368:9: note: template argument deduction/substitution failed:
/usr/include/c++/4.8/bits/stl_algobase.h:390:70: note: deduced conflicting types for parameter ‘_Tp’ (‘int’ and ‘const int’)
_Category>::__copy_m(__first, __last, __result);
^
Why does this happen? Should I not call reserve on a vector of const elements? If so, why not?
You are violating the requirements for the elements stated by the class vector. An element must be CopyAssignable.
const int is not a valid type to put into any standard container since it is not assignable.
This question already has answers here:
Can I use const in vectors to allow adding elements, but not modifications to the already added?
(14 answers)
Does C++11 allow vector<const T>?
(5 answers)
Closed 6 years ago.
I encountered this problem maintaining a port for a large (relative to the size of our team) project, but it was simple to create a small example.
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;
}
Looks correct, right? MSVS thinks so too. However:
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*’
With stack<string> strstack; it's all clean. Is this a g++ bug? Is there a workaround so that we won't have to drop the const until the bug is fixed?
The members of a standard container have to be copy assignable or movable (C++11). If the type is const it fails the requirements.
It is possible for the container to hold pointers (or preferably, smart pointers) to constants. This maintains the desired const semantics, although perhaps the syntax is a bit more clunky.
For example:
stack<shared_ptr<string const>> s;
s.push(make_shared<string>("foo"));
cout << *s.top() << endl;
For more info see this question.