如何传递std::array指针数组,限制函数修改指针指向的值?
解决std::array指针数组的函数访问限制问题
问题背景
我需要创建一个std::array指针数组,指针指向的类型不声明为const,这样我自己可以解引用指针修改指向的值:
#include <array> int main() { int a = 5; int b = 10; std::array<int*, 2> arr = { &a, &b }; // 不带const,允许修改指向的值 *(arr[0]) = 20; // 这行代码可以正常执行 }
但我希望把这个数组传给函数时,函数无法通过解引用数组中的指针修改其指向的值。目前的写法做不到:
#include <array> void test(const std::array<int*, 2>& arr) { *(arr[0]) = 20; // 这行代码仍然能执行,不符合需求 } int main() { int a = 5; int b = 10; std::array<int*, 2> arr = { &a, &b }; test(arr); }
而C风格数组可以通过int const * const * const参数实现这个限制:
void test(int const * const * const arr) { *(arr[0]) = 20; // 这行代码会编译报错,符合需求 } int main() { int a = 5; int b = 10; int* arr[2] = {&a, &b}; test(arr); }
想知道C++的std::array该怎么实现同样的效果?
解决方案
关键是要把std::array的元素类型从int*转换成const int*,同时保证数组本身不可修改(不能替换数组里的指针),对应C数组int const * const * const的三层const限制。
方法1:指定std::array<const int*, 2>作为函数参数
直接将函数参数的std::array元素类型改为const int*,传递时std::array<int*, 2>可以隐式转换为std::array<const int*, 2>(因为int*可以安全转换为const int*):
#include <array> void test(const std::array<const int*, 2>& arr) { *(arr[0]) = 20; // 编译报错:无法通过const指针修改指向的值 // arr[0] = &b; // 同样编译报错:无法修改const数组中的元素 } int main() { int a = 5; int b = 10; std::array<int*, 2> arr = { &a, &b }; test(arr); // 隐式转换合法 }
这里的const std::array<const int*, 2>&完全对应C数组的int const * const * const:
- 外层的
const:限制不能修改数组本身(比如替换数组里的指针) - 元素类型
const int*:限制不能解引用指针修改指向的值
方法2:模板函数适配任意大小的数组
如果不想固定数组的大小,可以用模板函数让编译器自动推导数组长度:
#include <array> #include <cstddef> template <std::size_t N> void test(const std::array<const int*, N>& arr) { *(arr[0]) = 20; // 编译报错 } int main() { int a = 5; int b = 10; std::array<int*, 2> arr = { &a, &b }; test(arr); }
为什么原写法无效?
原代码中的const std::array<int*, 2>&,这里的const仅修饰std::array容器本身,意味着你不能修改数组里的指针(比如arr[0] = &b;会报错),但数组内的元素仍然是int*类型,所以解引用后依然可以修改指向的值,这和你想要的限制不符。
内容的提问来源于stack exchange,提问作者VincentSchaerl
相关产品推荐
相关产品推荐

