なぜ自分のコードをコンパイルできないのか不思議です。下は大丈夫ですか?Category1 と Category2 の typedef-s を使用して単純なクラスを宣言しようとしています。
カテゴリ 1 の typedef は正常にコンパイルされますが、カテゴリ 2 のタイプ定義はコンパイルされません。
周囲のクラス X がインスタンス化されていないにもかかわらず、クラス iterator_traits<> がインスタンス化されているため、Category2 typedef をコンパイルできないようです...私にとって非常に混乱しているようです。
#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;
};
私の場合は、コンストラクターでラムダを取得するクラスを宣言したいということです。ラムダはコンテナへの参照を返すことが期待されています。そして、返されたコンテナーにランダム アクセス イテレーターがあるかどうかを判断する必要があります。しかし、私はこのコンパイルエラーに行き詰まりました。説明ありがとう!