Why is a vector of pointers not castable to a const vector of const pointers?(为什么指针向量不能转换为 const 指针的 const 向量?)
问题描述
The type vector<char *>
is not convertible to const vector<const char*>
. For example, the following gives a compilation error:
#include <vector>
using namespace std;
void fn(const vector<const char*> cvcc)
{
}
int main()
{
vector<char *> vc = vector<char *>();
fn(vc);
}
I understand why vector<char*>
is not convertable to vector<const char*>
- extra members of type const char *
may be added to the vector, and afterwards they would be accessible as non-const. However, if the vector itself is const, this can't happen.
My best guess is that this would be harmless, but there is no way the compiler is allowed to deduce that this would be harmless.
How can this be worked around?
This question was suggested by the C++ FQA here.
void fn(const vector<const char*>)
As the top-level const
qualifier is dropped for the function type, this is (at the call site) equivalent to:
void fn(vector<const char*>)
Both of which request a copy of the passed vector, because Standard Library containers follow value semantics.
You can either:
- call it via
fn({vc.begin(), vc.end()})
, requesting an explicit conversion - change the signature to, e.g.
void fn(vector<const char*> const&)
, i.e. taking a reference
If you can modify the signature of fn
, you can follow GManNickG's advice and use iterators / a range instead:
#include <iostream>
template<typename ConstRaIt>
void fn(ConstRaIt begin, ConstRaIt end)
{
for(; begin != end; ++begin)
{
std::cout << *begin << std::endl;
}
}
#include <vector>
int main()
{
char arr[] = "hello world";
std::vector<char *> vc;
for(char& c : arr) vc.push_back(&c);
fn(begin(vc), end(vc));
}
This gives the beautiful output
hello world ello world llo world lo world o world world world orld rld ld d
The fundamental issue is to pass around Standard Library containers. If you only need constant access to the data, you don't need to know the actual container type and can use the template instead. This removes the coupling of fn
to the type of container the caller uses.
As you have noticed, it's a bad idea to allow access of a std::vector<T*>
through a std::vector<const T*>&
. But if you don't need to modify the container, you can use a range instead.
If the function fn
shall not or cannot be a template, you could still pass around ranges of const char*
instead of vectors of const char
. This will work with any container that guarantees contiguous storage, such as raw arrays, std::array
s, std::vector
s and std::string
s.
这篇关于为什么指针向量不能转换为 const 指针的 const 向量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:为什么指针向量不能转换为 const 指针的 const 向量?


基础教程推荐
- C++结构和函数声明。为什么它不能编译? 2022-11-07
- 这个宏可以转换成函数吗? 2022-01-01
- 如何检查GTK+3.0中的小部件类型? 2022-11-30
- 常量变量在标题中不起作用 2021-01-01
- 静态库、静态链接动态库和动态链接动态库的 .lib 文件里面是什么? 2021-01-01
- 如何将 std::pair 的排序 std::list 转换为 std::map 2022-01-01
- 如何通过C程序打开命令提示符Cmd 2022-12-09
- 如何在 C++ 中初始化静态常量成员? 2022-01-01
- 我有静态或动态 boost 库吗? 2021-01-01
- 在 C++ 中计算滚动/移动平均值 2021-01-01