Ошибка gcc при объявлении ссылки на тип ссылки

В библиотеке 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) {

Странно то, что эта ошибка возникает только при использовании GCC 4.8.1 в среде Cray. Компиляция в обычной среде Linux с GCC 4.8.1 работает без ошибок.
На первый взгляд я бы сказал, что ссылка на ссылочный тип в любом случае не очень значима, но мне любопытно, что может вызвать другое поведение компилятора !?

1

Решение

Это похоже на разницу C ++ 03 / C ++ 11.

В C ++ 11 дополнительный &const, кстати) должны игнорироваться

[C++11: 8.3.2/6]: Если typedef (7.1.3), шаблон-параметр типа (14.3.1) или спецификатор decltype (7.1.6.2) обозначает тип TR это ссылка на тип Tпопытка создать ссылку типа lvalue на резюме TRСоздает тип «lvalue ссылка на T», при попытке создать тип «rvalue ссылка на резюме 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]: [..] Cv-квалифицированные ссылки некорректны, за исключением случаев, когда cv-квалификаторы вводятся посредством использования typedef (7.1.3) или аргумента типа шаблона (14.3), и в этом случае cv-квалификаторы игнорируются. [..]

Тем не менее [C++11: 8.3.2/6] формулировка не существует в C ++ 03! Фактически, мы можем сравнить поведение между двумя языками с помощью следующего примера программы:

struct T1 {};

typedef T1& T2;

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

(игнорирование предупреждений о неиспользуемых переменных)

Поэтому проверьте флаги компиляции на каждой платформе, чтобы убедиться, что вы используете один и тот же язык на обеих платформах. Может случиться так, что по умолчанию на Cray будет C ++ 03, но на вашей платформе по умолчанию будет C ++ 11. Использовать -std=c++03/-std=c++11 флаг, чтобы указать, что использовать явно.

5

Другие решения

Ссылки на ссылки (как const const) должны игнорироваться, чтобы упростить программирование мета-шаблонов, поэтому ошибка, которую вы видите в системе Cray, является ошибкой.

1