Неожиданное создание шаблона, приводящее к ошибке компиляции

Мне просто интересно, почему мой код не может быть скомпилирован. С нижним окей все в порядке? Я пытаюсь объявить простой класс с Type1 и Category2 typedef-s.

Категория1 typedef компилируется нормально, а Категория2 — нет.

Кажется, что Type2 typedef не может быть скомпилирован, потому что класс iterator_traits<> Создается экземпляр, несмотря на то, что окружающий класс X не создается … Кажется, меня очень смущает.

#include <iterator>

template <class GetterFunType>
struct X {
GetterFunType containerGetterFun;

// works
typedef typename std::iterator_traits<typename GetterFunType::iterator>::iterator_category Category1;

// compile error - std::iterator_traits<> is instantiated with type 'unknown'
typedef typename std::iterator_traits<
decltype(containerGetterFun().begin())>::iterator_category Category2;

X(GetterFunType _containerGetterFun) : containerGetterFun(_containerGetterFun) { }
};

Обратите внимание, что мне не нужно создавать экземпляр класса X для получения следующих ошибок (выше приведен полный блок компиляции).

В Visual Studio 2012 я получаю это:

1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364): error C2146: syntax error : missing ';' before identifier 'iterator_category'
1>          c:\data\fsl\apif_src_review\apif_src\systemns.cpp(11) : see reference to class template instantiation 'std::iterator_traits<_Iter>' being compiled
1>          with
1>          [
1>              _Iter=unknown
1>          ]
1>          c:\data\fsl\apif_src_review\apif_src\systemns.cpp(14) : see reference to class template instantiation 'X<GetterFunType>' being compiled
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364): error C3254: 'std::iterator_traits<_Iter>' : class contains explicit override 'iterator_category' but does not derive from an interface that contains the function declaration
1>          with
1>          [
1>              _Iter=unknown
1>          ]
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364): error C2838: 'iterator_category' : illegal qualified name in member declaration
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364): error C2602: 'std::iterator_traits<_Iter>::iterator_category' is not a member of a base class of 'std::iterator_traits<_Iter>'
1>          with
1>          [
1>              _Iter=unknown
1>          ]
1>          c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364) : see declaration of 'std::iterator_traits<_Iter>::iterator_category'
1>          with
1>          [
1>              _Iter=unknown
1>          ]
1>c:\program files (x86)\microsoft visual studio 11.0\vc\include\xutility(364): error C2868: 'std::iterator_traits<_Iter>::iterator_category' : illegal syntax for using-declaration; expected qualified-name
1>          with
1>          [
1>              _Iter=unknown
1>          ]

В xutility (364) есть:

template<class _Iter>
struct iterator_traits
{   // get traits from iterator _Iter
typedef typename _Iter::iterator_category iterator_category;
typedef typename _Iter::value_type value_type;
typedef typename _Iter::difference_type difference_type;
typedef difference_type distance_type;  // retained
typedef typename _Iter::pointer pointer;
typedef typename _Iter::reference reference;
};

В моем случае я хочу объявить класс, который получает лямбда-конструктор. Ожидается, что лямбда вернет ссылку на контейнер. И мне нужно определить, есть ли в возвращаемом контейнере итератор с произвольным доступом. Но я застрял с этой ошибкой компиляции. Спасибо за объяснение!

1

Решение

Мне удалось скомпилировать тот же код без каких-либо ошибок, используя gcc 5.3.1, с -std = c ++ 11

Ваш компилятор является относительно старым компилятором, который не поддерживает текущий стандарт C ++ 1x. Переключение на другой компилятор — единственная опция, которую я вижу здесь, если вам нужно использовать современные функции C ++.

1

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

Я вижу, что код в порядке, но есть некоторые ограничения Visual Studio 2012, не позволяющие компилировать. По крайней мере, в MSVS 2015 он работает так же, как и для gcc 5.3.1. Спасибо, друзья!

0

По вопросам рекламы [email protected]