В библиотеке 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 работает без ошибок.
На первый взгляд я бы сказал, что ссылка на ссылочный тип в любом случае не очень значима, но мне любопытно, что может вызвать другое поведение компилятора !?
Это похоже на разницу 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;
}
error: cannot declare reference to 'T2 {aka struct T1&}'
(игнорирование предупреждений о неиспользуемых переменных)
Поэтому проверьте флаги компиляции на каждой платформе, чтобы убедиться, что вы используете один и тот же язык на обеих платформах. Может случиться так, что по умолчанию на Cray будет C ++ 03, но на вашей платформе по умолчанию будет C ++ 11. Использовать -std=c++03
/-std=c++11
флаг, чтобы указать, что использовать явно.
Ссылки на ссылки (как const const
) должны игнорироваться, чтобы упростить программирование мета-шаблонов, поэтому ошибка, которую вы видите в системе Cray, является ошибкой.