У меня есть шаблонный класс, который имеет зависимые типы как typedefs, используемые в качестве параметров функции:
template <typename T > struct Foo {
typedef typename std::vector<T>::iterator Iterator;
inline void bar( const Iterator& it ) const;
std::vector<T> vec;
};
Теперь Visual Studio (2015) и GCC (5) имеют противоречивые взгляды на правильное объявление функции bar()
вне класса Foo
,
Первоначально я написал это так в Linux, который GCC скомпилировал счастливо:
template <typename T>
inline void Foo<T>::bar( const Foo<T>::Iterator& it ) const {}
Теперь, пытаясь скомпилировать в Visual Studio 2015, я получаю следующее сообщение об ошибке
1>main.cpp(14): error C2065: 'it': undeclared identifier
1>main.cpp(14): warning C4346: 'Foo<T>::Iterator': dependent name is not a type
1> main.cpp(14): note: prefix with 'typename' to indicate a type
Таким образом, кажется, что VS требует typename
Ключевое слово, которое будет присутствовать перед Iterator
, Хорошо. Я добавил его, но теперь он отказывается компилировать в GCC.
main.cpp:14:35: error: variable or field 'bar' declared void
inline void Foo<T>::bar( typename const Foo<T>::Iterator& it ) const {}
Вы можете увидеть это в прямом эфире здесь http://ideone.com/EaUeus
Так что мой вопрос … кто прав? Есть ли способ заставить этот код компилироваться на обеих платформах, не прибегая к #ifdef
?
Вы должны использовать const typename
не typename const
, Компилятор не может этого знать Foo<T>::Iterator
это тип, и const
можно использовать только для типов. Итак, сначала скажите, что это тип, а затем сделайте это const
,
Других решений пока нет …