将引用用作 array/pointer 是否合法?
Is it legal c++ to use reference as array/pointer?
我的团队(包括我自己)是 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++ 吗,即是否保证指向数组引用的指针指向原始数组?
有什么理由可以这样做而不是直接使用指针而不是使用引用作为中间值?
My team (including myself) is new to C++. ...
[...]
... something that should be discouraged.
你现在应该养成使用标准 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
-ness .
如果您想“全力以赴”使用 C++,可以使用模板使 the_cpp_wrapper()
更通用一些:
template<typename TSpan>
void the_cpp_wrapper(const TSpan& v)
{
the_c_function(v.data(), v.size());
}
使用此代码,您可以将任何具有 data()
和 size()
方法的内容传递给 the_cpp_wrapper
。 (请注意,TSpan
“可以”是 std::span<int>
,这可能会导致一些模糊的编译器错误;有一些方法可以解决这个问题,但更多的是 C++。)
没有直接关系,但您可能会发现 std::span
也很有用。
是的,这是合法的,并且保证根据您的代码引用数组中的原始元素。
有些人喜欢设计接口强制调用者通过引用传递,以避免检查参数是否为空指针,这在指针传递时可能需要。
抛开代码可读性的问题,
is it guaranteed that a pointer to a reference of an array points to the original array?
是的,见§ 5.5表达式:
If an expression initially has the type “reference to T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted to T
prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
和§8.3.2参考文献:
4 It is unspecified whether or not a reference requires storage.
5 There shall be no references to references, no arrays of references, and no pointers to references.
换句话说,“引用地址”不是一个东西;给定 double& dref
,取地址 &dref
将给出数组中原始元素的地址。
我的团队(包括我自己)是 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++ 吗,即是否保证指向数组引用的指针指向原始数组?
有什么理由可以这样做而不是直接使用指针而不是使用引用作为中间值?
My team (including myself) is new to C++. ...
[...]
... something that should be discouraged.
你现在应该养成使用标准 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
-ness .
如果您想“全力以赴”使用 C++,可以使用模板使 the_cpp_wrapper()
更通用一些:
template<typename TSpan>
void the_cpp_wrapper(const TSpan& v)
{
the_c_function(v.data(), v.size());
}
使用此代码,您可以将任何具有 data()
和 size()
方法的内容传递给 the_cpp_wrapper
。 (请注意,TSpan
“可以”是 std::span<int>
,这可能会导致一些模糊的编译器错误;有一些方法可以解决这个问题,但更多的是 C++。)
没有直接关系,但您可能会发现 std::span
也很有用。
是的,这是合法的,并且保证根据您的代码引用数组中的原始元素。
有些人喜欢设计接口强制调用者通过引用传递,以避免检查参数是否为空指针,这在指针传递时可能需要。
抛开代码可读性的问题,
is it guaranteed that a pointer to a reference of an array points to the original array?
是的,见§ 5.5表达式:
If an expression initially has the type “reference to
T
” ([dcl.ref], [dcl.init.ref]), the type is adjusted toT
prior to any further analysis. The expression designates the object or function denoted by the reference, and the expression is an lvalue or an xvalue, depending on the expression.
和§8.3.2参考文献:
4 It is unspecified whether or not a reference requires storage.
5 There shall be no references to references, no arrays of references, and no pointers to references.
换句话说,“引用地址”不是一个东西;给定 double& dref
,取地址 &dref
将给出数组中原始元素的地址。