C++使用引用作为数组/指针合法吗?

问题描述 投票:0回答:3

我的团队(包括我自己)是 C++ 新手。我们新开发的一个 C++ 函数需要与接受数组作为输入的 C 函数进行交互。为了实现这一点,做了类似以下的构造:

#include "stdio.h"

void the_c_function(double *array, int len)
{
   for (int i = 0; i < len; i++)
   {
      printf("%d: %g\n", i, array[i]);
   }
}

void the_cpp_wrapper(double& dref, int len)
{
   the_c_function(&dref, len);
}

int main()
{
   const int LEN = 4;
   double dbl_array[LEN] = { 3,4,5,6 };
   the_cpp_wrapper(dbl_array[0], LEN);
   return 0;
}

编译后,这将按预期工作:它打印数组的内容:

0: 3
1: 4
2: 5
3: 6

但这对我来说几乎不合法,或者充其量是应该劝阻的。

这是合法的C++吗?即是否保证指向数组引用的指针指向原始数组?

有什么理由可以这样做,而不是直接使用指针而不是使用引用作为中间值?

c++ pointers reference
3个回答
5
投票

我的团队(包括我自己)是 C++ 新手。 ...

[...]

...应该劝阻的事情。

您现在应该养成使用标准 C++ 库的习惯,在您的情况下,最好的选择是

std::vector
:

#include <stdio.h>
#include <stdlib>
#include <vector>

void the_c_function(const double *array, size_t len) {/*...*/}
void the_cpp_wrapper(const std::vector<double>& v)
{
   the_c_function(v.data(), v.size());
}
// ----------------------------
int main()
{
   const std::vector<double> dbl_array { 3,4,5,6 };
   the_cpp_wrapper(dbl_array);
   return EXIT_SUCCESS;
}

您还应该更清楚地了解

const double*
double*
,C++ 故意希望您使用更冗长的
const_cast<double*>
来抛弃
const
性。

如果您想“全力以赴”使用 C++,您可以使用模板使

the_cpp_wrapper()
更加通用:

template<typename TSpan>
void the_cpp_wrapper(const TSpan& v)
{
   the_c_function(v.data(), v.size());
}

使用此代码,您可以将任何内容传递给具有

the_cpp_wrapper
data()
方法的
size()


不直接相关,但您可能会发现

std::span
也很有用。


1
投票

抛开代码可读性问题,

是否保证指向数组引用的指针指向原始数组?

是的,请参阅§ 5.5 表达式:

如果表达式最初具有“对

T
的引用”类型([dcl.ref]、[dcl.init.ref]),则在进行任何进一步分析之前,将类型调整为
T
。表达式指定引用表示的对象或函数,并且表达式是左值或x值,具体取决于表达式。

§8.3.2参考文献:

4   未指定引用是否需要存储。

5   不得有对引用的引用,不得有引用数组,并且不得有指向引用的指针

换句话说,“引用的地址”不是一个东西;而是一个东西。给定

double& dref
,获取地址
&dref
将给出数组内原始元素的地址。


0
投票

是的,这是合法的,并且保证根据您的代码引用数组中的原始元素。

有些人喜欢设计接口来强制调用者通过引用传递,以避免检查参数是否是

NULL
指针,这在通过指针传递时可能需要。

© www.soinside.com 2019 - 2024. All rights reserved.