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!?
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 typeTR
that is a reference to a typeT
, an attempt to create the type “lvalue reference to cvTR
” creates the type “lvalue reference toT
”, while an attempt to create the type “rvalue reference to cvTR
” creates the typeTR
.[ 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;
}
error: cannot declare reference to 'T2 {aka struct T1&}'
(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.