Question

In the OpenCV library there is a

typedef const _InputArray& InputArray;

In our code we have the following function definition:

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

When compiling this the following error occurs:

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

The weird thing is that this error only occurs using GCC 4.8.1 in the Cray environment. Compiling in a normal Linux environment with GCC 4.8.1 works without errors.
At first glance I would say that a reference to a reference type is not very meaningful anyway but I am curious about what could cause the different compiler behavior!?

Was it helpful?

Solution

This appears to be a C++03/C++11 difference.

In C++11, the extra & (and the const, incidentally) are supposed to be ignored:

[C++11: 8.3.2/6]: If a typedef (7.1.3), a type template-parameter (14.3.1), or a decltype-specifier (7.1.6.2) denotes a type TR that is a reference to a type T, an attempt to create the type “lvalue reference to cv TR” creates the type “lvalue reference to T, while an attempt to create the type “rvalue reference to cv TR” creates the type TR.

[ Example:

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&

—end example ]

The pertinent example here is r1; although typedef int& LRI isn't precisely like your typedef, the example is equivalent due to the following passage having already dropped your const:

[C++11: 8.3.2/1]: [..] Cv-qualified references are ill-formed except when the cv-qualifiers are introduced through the use of a typedef (7.1.3) or of a template type argument (14.3), in which case the cv-qualifiers are ignored. [..]

However, the [C++11: 8.3.2/6] wording does not exist in C++03! In fact, we can compare behaviours between the two languages with the following example program:

struct T1 {};

typedef T1& T2;

int main()
{
    T1 x;
    T2& t = x;
}

(ignoring warnings about unused variables)

So, check your compilation flags on each platform to ensure that you're using the same language on both. It may be that the default on the Cray is C++03, but the default on your platform is C++11. Use the -std=c++03/-std=c++11 flag to state which to use explicitly.

OTHER TIPS

References to references (as const const) are supposed to be ignored to make meta-template programming easier, So the error you're seeing on the Cray system is a bug.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top