首页 > 解决方案 > 在 C++ 中将动态声明的数组作为常量传递

问题描述

标签: c++

解决方案


OP签名的原因

func(const double ** array){
    // computations using array
}

当 a 作为参数传递时会产生错误double **,在于限定转换的规则。

引用https://en.cppreference.com/w/cpp/language/implicit_conversion(强调我的):

资格转换

  • 指向 cv 限定类型 T 的类型指针的纯右可以转换为指向更多cv 限定的相同类型 T 的纯右值指针(换句话说,可以添加 constness 和易失性)。
  • [...]

“更多” cv-qualified 意味着

  • 指向非限定类型的指针可以转换为指向 const 的指针;
  • [...]

对于多级指针,以下限制适用:多级指针 P1 是cv 1 0限定指针,指向cv 1 1限定指针 ... cv 1 n-1限定指针,指向cv 1 n限定 T 是可转换为多级指针 P2,它是cv 2 0 -qualified pointer to cv 2 1 -qualified pointer to ... cv 2 n-1 -qualified pointer to cv 2 n -qualified T 仅当

  • 两个指针的层数 n 相同;
  • 如果在P1 的某个级别(零级除外)的cv 1 k资格中有一个 const,则在 P2 的同一级别cv 2 k中有一个 const;
  • [...]
  • 如果在某个级别 k 上,P2 比 P1 更符合 cv 要求,那么直到 k 为止,P2 的每个级别(除了零级别)都必须有一个 constcv 2 1 , cv 2 2 ... cv 2 k .
  • [...]
  • 零级由非多级资格转换规则解决。
字符** p = 0;
常量字符** p1 = p; // 错误:级别 2 更多 cv 限定但级别 1 不是 const
常量字符 * 常量 * p2 = p; // OK: level 2 more cv-qualified and
                            // 在第 1 层添加 const

请注意,在 C 编程语言中,const/volatile 只能添加到第一级:

字符** p = 0;
字符 * 常量 * p1 = p; // 在 C 和 C++ 中可以
常量字符 * 常量 * p2 = p; // C 语言错误,C++ 语言正常

因此,为了强制执行 constness,需要将签名更改为

void func(double const * const * array) {
    // ...               ^^^^^ 
}

也就是说,如果可能的话,我强烈建议改变整体设计并避免动态分配的锯齿状数组。


推荐阅读