简体   繁体   English

在C ++中将动态声明的数组作为常量传递

[英]passing dynamically declared array as constant in c++

I dynamically created an array using a function like this: 我使用如下函数动态创建了一个数组:

//..
    double ** allocate_2d(const int wd1, const int wd2){
    double **array = new double*[wd1];

    for(int idx=0; idx<wd1; idx++)
    {
        array[idx] = new double[wd2];
    }

    return array;
}

I would like to pass the resulting array into a function as a constant parameter. 我想将结果数组作为常量参数传递给函数。 I want the array to be "read only" within the function. 我希望函数内的数组为“只读”。

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

However I get the following error: invalid conversion from 'double**' to 'const double**' 但是我收到以下错误: invalid conversion from 'double**' to 'const double**'

Is it possible to do something like this? 有可能做这样的事情吗?

The reason why OP's signature OP之所以签名

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

generates an error when a double ** is passed as an argument, lies in the rules of qualification conversions. 当将double **作为参数传递时,会产生错误,这double **资格转换的规则。

Quoting https://en.cppreference.com/w/cpp/language/implicit_conversion (emphasis mine): 引用https://en.cppreference.com/w/cpp/language/implicit_conversion (重点是我的):

Qualification conversions 资格转换

  • A prvalue of type pointer to cv-qualified type T can be converted to a prvalue pointer to a more cv-qualified same type T (in other words, constness and volatility can be added). prvalue类型的指针,以CV-合格类型T可以被转换为一个prvalue指针 CV-合格相同类型T(换言之,常量性和波动可添加)。
  • [...] [...]

"More" cv-qualified means that “更多”具有简历资格意味着

  • a pointer to unqualified type can be converted to a pointer to const; 指向非限定类型的指针可以转换为指向const的指针;
  • [...] [...]

For multi-level pointers, the following restrictions apply: a multilevel pointer P1 which is cv 1 0 -qualified pointer to cv 1 1 -qualified pointer to ... cv 1 n-1 -qualified pointer to cv 1 n -qualified T is convertible to a multilevel pointer P2 which is cv 2 0 -qualified pointer to cv 2 1 -qualified pointer to ... cv 2 n-1 -qualified pointer to cv 2 n -qualified T only if 对于多级指针,以下限制适用: cv 1 0合格指针cv 1 1合格指针... ... cv 1 n-1合格指针cv 1 n合格指针T1转换为多级指针P2其是CV 2 0 -qualified指向cv 2 1 -qualified指针... CV 2 n-1个 -qualified指向cv 2 n个 -qualified只有T如果

  • the number of levels n is the same for both pointers; 两个指针的级别数n相同;
  • if there is a const in the cv 1 k qualification at some level (other than level zero) of P1, there is a const in the same level cv 2 k of P2; 如果在P1的某个级别(零级别除外)的cv 1 k资格中存在const,则在P2的相同cv 2 k级别中存在const;
  • [...] [...]
  • if at some level k the P2 is more cv-qualified than P1, then there must be a const at every single level (other than level zero) of P2 up until k : cv 2 1 , cv 2 2 ... cv 2 k . 如果在某个k级别,P2比c1更具有cv资格,则在p2的每个单个级别(零级别除外)上都必须有一个常量,直到kcv 2 1cv 2 2 ... cv 2 k
  • [...] [...]
  • level zero is addressed by the rules for non-multilevel qualification conversions. 非多级资格转换的规则解决了零级问题。
\nchar** p = 0; char ** p = 0;\nconst char** p1 = p; const char ** p1 = p; // error: level 2 more cv-qualified but level 1 is not const //错误:等级2更具有简历资格,但等级1不是const\nconst char* const * p2 = p; const char * const * p2 = p; // OK: level 2 more cv-qualified and //好:再通过2级cv认证,并且 \n                            // const added at level 1 //在第1级添加const\n

Note that in the C programming language, const/volatile can be added to the first level only: 请注意,在C编程语言中,只能将const / volatile添加到第一级:

\nchar** p = 0; char ** p = 0;\nchar * const* p1 = p; char * const * p1 = p; // OK in C and C++ //在C和C ++中可以\nconst char* const * p2 = p; const char * const * p2 = p; // error in C, OK in C++ // C中的错误,在C ++中可以\n

So, to enforce constness, the signature needs to be changed into 因此,为了增强一致性,需要将签名更改为

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

That said, I strongly suggest to change the overall design and avoid that dynamically allocated jagged array, if possible. 也就是说,我强烈建议更改整体设计,并尽可能避免使用动态分配的锯齿状数组。

You can use const_cast to add constness to an object (explicit cast is needed). 您可以使用const_cast向对象添加常量(需要显式强制const_cast )。

double **p = allocate_2d(100,200);

// populate p

func(const_cast<const double**>(p));//array pointed by p will be read only inside func

Still, you need to consider whether you need const there at all. 不过,您仍然需要考虑是否根本需要const

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM