0

I am trying to write functions that would accept as parameter a reference to a container containing constant values. For example :

#include<string>
#include<vector>

using std::string;
using std::vector;

extern void eval (vector<const string>&);

void entry(vector<const string>& p)
{
    vector<const string> l;
    eval(l);
    eval(p);
}

Both g++ 7.5.0 and clang 6.0.0 reject this code.

In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
                 from /usr/include/c++/7/bits/allocator.h:46,
                 from /usr/include/c++/7/string:41,
                 from bug.cpp:1:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const std::__cxx11::basic_string<char> >’:
/usr/include/c++/7/bits/allocator.h:108:11:   required from ‘class std::allocator<const std::__cxx11::basic_string<char> >’
/usr/include/c++/7/bits/stl_vector.h:81:14:   required from ‘struct std::_Vector_base<const std::__cxx11::basic_string<char>, std::allocator<const std::__cxx11::basic_string<char> > >::_Vector_impl’
/usr/include/c++/7/bits/stl_vector.h:166:20:   required from ‘struct std::_Vector_base<const std::__cxx11::basic_string<char>, std::allocator<const std::__cxx11::basic_string<char> > >’
/usr/include/c++/7/bits/stl_vector.h:216:11:   required from ‘class std::vector<const std::__cxx11::basic_string<char> >’
bug.cpp:11:26:   required from here
/usr/include/c++/7/ext/new_allocator.h:93:7: error: ‘const _Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::const_reference) const [with _Tp = const std::__cxx11::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::const_pointer = const std::__cxx11::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::const_reference = const std::__cxx11::basic_string<char>&]’ cannot be overloaded
       address(const_reference __x) const _GLIBCXX_NOEXCEPT
       ^~~~~~~
/usr/include/c++/7/ext/new_allocator.h:89:7: error: with ‘_Tp* __gnu_cxx::new_allocator<_Tp>::address(__gnu_cxx::new_allocator<_Tp>::reference) const [with _Tp = const std::__cxx11::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::__cxx11::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::reference = const std::__cxx11::basic_string<char>&]’
       address(reference __x) const _GLIBCXX_NOEXCEPT
       ^~~~~~~
/usr/include/c++/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::__cxx11::basic_string<char>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::__cxx11::basic_string<char>*; __gnu_cxx::new_allocator<_Tp>::size_type = long unsigned int]’:
/usr/include/c++/7/bits/alloc_traits.h:462:9:   required from ‘static void std::allocator_traits<std::allocator<_CharT> >::deallocate(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, std::allocator_traits<std::allocator<_CharT> >::pointer, std::allocator_traits<std::allocator<_CharT> >::size_type) [with _Tp = const std::__cxx11::basic_string<char>; std::allocator_traits<std::allocator<_CharT> >::allocator_type = std::allocator<const std::__cxx11::basic_string<char> >; std::allocator_traits<std::allocator<_CharT> >::pointer = const std::__cxx11::basic_string<char>*; std::allocator_traits<std::allocator<_CharT> >::size_type = long unsigned int]’
/usr/include/c++/7/bits/stl_vector.h:180:19:   required from ‘void std::_Vector_base<_Tp, _Alloc>::_M_deallocate(std::_Vector_base<_Tp, _Alloc>::pointer, std::size_t) [with _Tp = const std::__cxx11::basic_string<char>; _Alloc = std::allocator<const std::__cxx11::basic_string<char> >; std::_Vector_base<_Tp, _Alloc>::pointer = const std::__cxx11::basic_string<char>*; std::size_t = long unsigned int]’
/usr/include/c++/7/bits/stl_vector.h:162:22:   required from ‘std::_Vector_base<_Tp, _Alloc>::~_Vector_base() [with _Tp = const std::__cxx11::basic_string<char>; _Alloc = std::allocator<const std::__cxx11::basic_string<char> >]’
/usr/include/c++/7/bits/stl_vector.h:263:15:   required from ‘std::vector<_Tp, _Alloc>::vector() [with _Tp = const std::__cxx11::basic_string<char>; _Alloc = std::allocator<const std::__cxx11::basic_string<char> >]’
bug.cpp:11:26:   required from here

When I remove the const from the container element types, the code is accepted :

#include<string>
#include<vector>

using std::string;
using std::vector;

extern void eval (vector<string>&);

void entry(vector<string>& p)
{
    vector<string> l;
    eval(l);
    eval(p);
}

Why is that?

dde
  • 150
  • 6
  • 1
    gcc makes is pretty clear: _"stl_vector.h:401:66: error: static assertion failed: std::vector must have a non-const, non-volatile value_type"_ The type of a vector has to be copy assignable until C++11 and `const` is not assignable. I'd say later versions have similar requirements. – Thomas Sablik Nov 06 '20 at 09:54
  • @ThomasSablik which version of gcc are you using? The output I pasted into my question does not contain the error message that you provided me, which would indeed have been helpful. – dde Nov 06 '20 at 10:08
  • https://wandbox.org/permlink/coug1GVnrlkqqgMP – Thomas Sablik Nov 06 '20 at 10:08
  • For the record: gcc 10.1.0, std=c++17 Thank you. – dde Nov 06 '20 at 10:16

1 Answers1

0

The answer is in the comment sections: "The type of a vector has to be copy assignable until C++11 and const is not assignable".

dde
  • 150
  • 6