【问题标题】:Unexpected template instantiation leading to a compile error意外的模板实例化导致编译错误
【发布时间】:2016-04-15 17:22:01
【问题描述】:

我只是想知道为什么我的代码无法编译。下面的好吗?我正在尝试使用 Category1 和 Category2 typedef-s 声明一个简单的类。

Category1 typedef 可以正常编译,但 Category2 one 不能。

似乎无法编译 Category2 typedef,因为尽管未实例化周围的类 X,但仍实例化了类 iterator_traits... 对我来说似乎很困惑。

#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;
    };

我的情况是我想声明一个在构造函数中获取 lambda 的类。 lambda 应该返回对容器的引用。而且我需要确定返回的容器是否具有随机访问迭代器。但是我遇到了这个编译错误。谢谢你的解释!

【问题讨论】:

  • containerGetterFun() 替换为std::declval&lt;typename std::result_of&lt;GetterFunType()&gt;::type&gt;()?
  • @Yakk:没有变化...令人惊讶的是代码:typedef typename std::iterator_traits&lt; decltype(std::vector&lt;int&gt;().begin()) &gt;::iterator_category Category2; 不编译... - 即使非参数化类型用于iterator_traits
  • 不足为奇:2012 年对 decltype 的支持介于差和蹩脚之间。所以有一些查询成员存在的内置内在函数,也许有一个用于成员返回值? &amp;const_X::begin 可能是另一种值得考虑的方法。
  • 试试 MSVS 2015,它可以工作

标签: c++ templates visual-studio-2012 compiler-errors iterator-traits


【解决方案1】:

我能够使用 gcc 5.3.1 编译相同的代码而没有任何错误,使用 -std=c++11

您的编译器是一个相对较旧的编译器,不支持当前的 C++1x 标准。如果您需要使用现代 C++ 功能,切换到另一个编译器是我在这里看到的唯一选择。

【讨论】:

  • 哦,我明白了。明确的答案:代码没问题,V$ 是错误的 :) 我会尝试说服其他人迁移(至少迁移到较新的 VS)。谢谢。
【解决方案2】:

我看到代码没问题,但有一些 Visual Studio 2012 限制不允许编译。至少在 MSVS 2015 中它可以工作,与 gcc 5.3.1 相同。谢谢朋友们!

【讨论】:

    猜你喜欢
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 2012-02-18
    • 2017-06-19
    相关资源
    最近更新 更多