声明对引用类型的引用时出现 GCC 错误

gcc error when declaring reference to reference type

本文关键字:GCC 错误 引用 引用类型 声明      更新时间:2023-10-16

在OpenCV库中有一个

typedef const _InputArray& InputArray;

在我们的代码中,我们有以下函数定义:

void wimshow(const String& winName, InputArray &img) {

编译时,会发生以下错误:

error: cannot declare reference to 'cv::InputArray {aka const class cv::_InputArray&}' void wimshow(const String& winName, InputArray &img) {

奇怪的是,此错误仅在Cray环境中使用GCC 4.8.1发生。 使用 GCC 4.8.1 在正常的 Linux 环境中编译不会出错。
乍一看,我会说对引用类型的引用无论如何都不是很有意义,但我很好奇什么会导致不同的编译器行为!?

似乎是C++03/C++11的差异。

在 C++11 中,额外的&(顺便说一下,还有const(应该被忽略:

[C++11: 8.3.2/6]: 如果 typedef (7.1.3(、类型模板参数 (14.3.1( 或 decltype-specifier (7.1.6.2( 表示对类型T的引用的类型TR,则尝试创建类型"对 cv TR 的左值引用"将创建类型"对 T 的左值引用",而尝试创建类型"对 cv TR 的右值引用"将创建类型 TR

[ 示例:

int i;
typedef int& LRI;
typedef int&& RRI;
LRI& r1 = i;           // r1 has the type int&
const LRI& r2 = i;     // r2 has the type int&
const LRI&& r3 = i;    // r3 has the type int&
RRI& r4 = i;           // r4 has the type int&
RRI&& r5 = 5;          // r5 has the type int&&
decltype(r2)& r6 = i;  // r6 has the type int&
decltype(r2)&& r7 = i; // r7 has the type int&

—结束示例 ]

这里相关的例子是r1;虽然typedef int& LRI并不完全像你的typedef,但这个例子是等价的,因为下面的段落已经放弃了你的const

[C++11: 8.3.2/1]: [..]除非通过使用 typedef (7.1.3( 或模板类型参数 (14.3( 引入 cv 限定符,否则格式不正确,在这种情况下,将忽略 cv 限定符。[..]

但是,C++03 中不存在[C++11: 8.3.2/6]措辞!事实上,我们可以用以下示例程序比较两种语言之间的行为:

struct T1 {};
typedef T1& T2;
int main()
{
    T1 x;
    T2& t = x;
}
  • C++03 中的输出:error: cannot declare reference to 'T2 {aka struct T1&}'
  • C++11 中的输出:没有!

(忽略有关未使用变量的警告(

因此,请检查每个平台上的编译标志,以确保在两个平台上使用相同的语言。可能是Cray上的默认值为C++03,但您平台上的默认值为C++11。使用 -std=c++03/-std=c++11 标志来声明要显式使用哪个标志。

对引用的引用(如const const(应该被忽略以使元模板编程更容易,所以你在Cray系统上看到的错误是一个错误。