在函数签名中引用 const 的容器
Reference to container of const in function signature
我正在尝试编写接受对包含常量值的容器的引用作为参数的函数。例如:
#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);
}
g++ 7.5.0 和 clang 6.0.0 都拒绝此代码。
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
当我从容器元素类型中删除 const
时,代码被接受:
#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);
}
这是为什么?
答案在评论部分:“在 C++11 之前,向量的类型必须是可复制赋值的,而 const 是不可赋值的”。
我正在尝试编写接受对包含常量值的容器的引用作为参数的函数。例如:
#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);
}
g++ 7.5.0 和 clang 6.0.0 都拒绝此代码。
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
当我从容器元素类型中删除 const
时,代码被接受:
#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);
}
这是为什么?
答案在评论部分:“在 C++11 之前,向量的类型必须是可复制赋值的,而 const 是不可赋值的”。