导致编译错误的意外模板实例化
Unexpected template instantiation leading to a compile error
我只是想知道为什么我的代码无法编译。下面的好吗?我正在尝试使用 Category1 和 Category2 typedef-s 声明一个简单的 class。
Category1 typedef 可以正常编译,但 Category2 不能。
似乎无法编译 Category2 typedef,因为 class iterator_traits<> 被实例化,尽管周围的 class 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) { }
};
注意我不需要实例化classX得到如下错误(以上是完整的编译单元)
在 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;
};
我的情况是我想声明一个 class 在构造函数中获取一个 lambda。 lambda 应 return 对容器的引用。我需要确定 returned 容器是否具有随机访问迭代器。但是我遇到了这个编译错误。谢谢解释!
我能够使用 gcc 5.3.1 和 -std=c++11
编译相同的代码而没有任何错误
你的编译器是比较老的编译器,不支持当前的C++1x标准。如果您需要使用现代 C++ 功能,切换到另一个编译器是我在这里看到的唯一选择。
我看到代码没问题,但有一些 Visual Studio 2012 限制不允许编译。至少在 MSVS 2015 中它可以工作,与 gcc 5.3.1 相同。谢谢朋友们!
我只是想知道为什么我的代码无法编译。下面的好吗?我正在尝试使用 Category1 和 Category2 typedef-s 声明一个简单的 class。
Category1 typedef 可以正常编译,但 Category2 不能。
似乎无法编译 Category2 typedef,因为 class iterator_traits<> 被实例化,尽管周围的 class 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) { }
};
注意我不需要实例化classX得到如下错误(以上是完整的编译单元)
在 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;
};
我的情况是我想声明一个 class 在构造函数中获取一个 lambda。 lambda 应 return 对容器的引用。我需要确定 returned 容器是否具有随机访问迭代器。但是我遇到了这个编译错误。谢谢解释!
我能够使用 gcc 5.3.1 和 -std=c++11
编译相同的代码而没有任何错误你的编译器是比较老的编译器,不支持当前的C++1x标准。如果您需要使用现代 C++ 功能,切换到另一个编译器是我在这里看到的唯一选择。
我看到代码没问题,但有一些 Visual Studio 2012 限制不允许编译。至少在 MSVS 2015 中它可以工作,与 gcc 5.3.1 相同。谢谢朋友们!