【问题标题】:Clang vs gcc std::crbegin with boost::iterator_rangeClang vs gcc std::crbegin with boost::iterator_range
【发布时间】:2016-12-17 03:15:23
【问题描述】:

带有 libc++ 的 Clang 3.8.1 编译以下程序:

#include <vector>
#include <iterator>
#include <algorithm>
#include <iostream>

#include <boost/range/iterator_range.hpp>

int main()
{
    const std::vector<int> v {1, 2, 3};

    const auto range = boost::make_iterator_range(v);

    std::copy(std::crbegin(range), std::crend(range), std::ostream_iterator<int> {std::cout, " "});
    std::cout << std::endl;

    return 0;
}

但是带有 libstdc++ 的 gcc 6.1.0 没有。 gcc 错误的第一行是:

error: no matching function for call to 'crbegin(const boost::iterator_range<__gnu_cxx::__normal_iterator<const int*, std::vector<int> > >&

谁是对的?

注意:Boost 1.61 版

【问题讨论】:

  • gcc 给出什么错误?
  • @aschepler 我已经添加了错误的第一行 - 其余的并没有增加太多。 std::crend 也一样。我实际上认为 gcc 在这里是正确的 - boost::iterator_range 中没有 rbeginrend 成员方法。我只是不太明白 Clang 是如何制作的!
  • @Daniel :您是在使用带有 libc++ 或 libstdc++ 的 Clang 吗?如果是前者,如果不存在rbegin 成员函数,它大概会调用std::make_reverse_iterator(range.begin())。如果是后者,那确实是个好问题……
  • @ildjarn libc++。这也是我的怀疑,但这是正确的行为吗?
  • @Daniel:我不知道,但如果这是您真正的问题,那么您需要在此处进行认真的编辑以反映这一点(可能还有language-lawyer 标签)。即,您的问题目前似乎是在询问 GCC,但您真正的问题是关于 libc++。

标签: c++ gcc boost clang c++14


【解决方案1】:

这是一个bug in libc++; std::crbegin 委派给 rbegin,但称它为不合格,它正在接手 boost::rbegin (documentation):

template <class _Cp>
inline _LIBCPP_INLINE_VISIBILITY
auto crbegin(const _Cp& __c) -> decltype(rbegin(__c))
{
    return rbegin(__c);
    //     ^-- unqualified, allows ADL
}

这与 [iterator.range] 相悖,后者表示 crbegin 应仅委托给 std::rbegin

template &lt;class C&gt; constexpr auto crbegin(const C&amp; c) -&gt; decltype(std::rbegin(c));

14 - 返回: std::rbegin(c)

Libc++ 对cbegincendcrend 的实现存在相同的错误。

【讨论】:

  • 感谢您的错误报告。
  • 现在已经修复了。
猜你喜欢
  • 2012-04-27
  • 2012-06-24
  • 2012-10-29
  • 2012-10-28
  • 2018-09-10
  • 2015-02-17
  • 2022-12-01
  • 2015-09-01
  • 2020-12-21
相关资源
最近更新 更多