1

なぜ自分のコードをコンパイルできないのか不思議です。下は大丈夫ですか?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;
    };

私の場合は、コンストラクターでラムダを取得するクラスを宣言したいということです。ラムダはコンテナへの参照を返すことが期待されています。そして、返されたコンテナーにランダム アクセス イテレーターがあるかどうかを判断する必要があります。しかし、私はこのコンパイルエラーに行き詰まりました。説明ありがとう!

4

2 に答える 2

0

コードは問題ないことがわかりましたが、Visual Studio 2012 にはコンパイルを許可しないいくつかの制限があります。少なくとも MSVS 2015 では、gcc 5.3.1 と同じように動作します。友よありがとう!

于 2016-01-11T13:03:02.730 に答える