Reputation: 1365
I consider myself fairly knowledgeable regarding the more basic aspects of C++, but sometimes I tend to get confused. I'm trying to implement a pair of functions that act on instances of std::vector
and do some operations with their values, without changing them in-place. Naturally, I thought that a pass by const&
would be a reasonable thing to do. However, the following MWE fails to compile, and I would like to understand why:
#include<vector>
void func1(const std::vector<const char* const>& v){
// do stuff
}
void func2(const std::vector<const std::vector<const char* const> >& v){
for(int i=0;i<v.size();++i){
func1(v[i]);
}
}
int main(){
return 0;
}
The error message looks somewhat like this:
In file included from...include/c++/4.9.3/x86_64-unknown-linux-gnu/bits/c++allocator.h:33:0,
from...include/c++/4.9.3/bits/allocator.h:46,
from...include/c++/4.9.3/vector:61,
from test.cxx:2:
.../ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const std::vector<const char* const> >’:
.../bits/allocator.h:92:11: required from ‘class std::allocator<const std::vector<const char* const> >’
.../ext/alloc_traits.h:172:53: required from ‘struct __gnu_cxx::__alloc_traits<std::allocator<const std::vector<const char* const> > >’
.../bits/stl_vector.h:75:28: required from ‘struct std::_Vector_base<const std::vector<const char* const>, std::allocator<const std::vector<const char* const> > >’
.../bits/stl_vector.h:214:11: required from ‘class std::vector<const std::vector<const char* const> >’
test.cxx:9:18: required from here
.../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::vector<const char* const>; __gnu_cxx::new_allocator<_Tp>::const_pointer = const std::vector<const char* const>*; __gnu_cxx::new_allocator<_Tp>::const_reference = const std::vector<const char* const>&]’ cannot be overloaded
address(const_reference __x) const _GLIBCXX_NOEXCEPT
^
.../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::vector<const char* const>; __gnu_cxx::new_allocator<_Tp>::pointer = const std::vector<const char* const>*; __gnu_cxx::new_allocator<_Tp>::reference = const std::vector<const char* const>&]’
address(reference __x) const _GLIBCXX_NOEXCEPT
^
.../ext/new_allocator.h: In instantiation of ‘class __gnu_cxx::new_allocator<const char* const>’:
.../bits/allocator.h:92:11: required from ‘class std::allocator<const char* const>’
.../ext/alloc_traits.h:172:53: required from ‘struct __gnu_cxx::__alloc_traits<std::allocator<const char* const> >’
.../bits/stl_vector.h:75:28: required from ‘struct std::_Vector_base<const char* const, std::allocator<const char* const> >’
.../bits/stl_vector.h:214:11: required from ‘class std::vector<const char* const>’
test.cxx:10:14: required from here
.../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 char* const; __gnu_cxx::new_allocator<_Tp>::const_pointer = const char* const*; __gnu_cxx::new_allocator<_Tp>::const_reference = const char* const&]’ cannot be overloaded
address(const_reference __x) const _GLIBCXX_NOEXCEPT
^
.../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 char* const; __gnu_cxx::new_allocator<_Tp>::pointer = const char* const*; __gnu_cxx::new_allocator<_Tp>::reference = const char* const&]’
address(reference __x) const _GLIBCXX_NOEXCEPT
I'm confused by the fact that the error message claims that something cannot be overloaded, referring to the call of func1
inside func2
. It seems like there's an issue with resolving the const
reference to the vector entry, but I really don't understand why this piece of code does not compile. I'm happy for any explanation, suggestion, or pointer to documentation about this type of behavior.
Upvotes: 2
Views: 4957
Reputation: 92311
The compiler reports its problem correctly, if you just know beforehand what that means.
The std::allocator
has two overloads for address
.
address(reference __x)
address(const_reference __x)
The problem for the compiler is that for a template type const T
, the two types T&
and const T&
will be the same type. And then it believes that there are two copies of the same overload.
Upvotes: 3
Reputation: 29017
std::vector<const char* const>
You are trying to instantiate a vector with a const
type. The type needs to be at least moveable, and that isn't. Change to:
std::vector<const char*>
instead
Upvotes: 4