【问题标题】:reference to 'end' is ambiguous when using std ranges使用标准范围时对“结束”的引用不明确
【发布时间】:2021-02-20 17:30:28
【问题描述】:

当我尝试编译以下代码时:

// This file is a "Hello, world!" in C++ language by GCC for wandbox.
#include <iostream>
#include <cstdlib>
#include <ranges>
#include <vector>
#include <numeric>
#include <cmath>

template <typename T>
struct Foo
{
  std::vector<T> vec;
  
  auto begin() { return vec.begin(); }
  auto end() { return vec.end(); }
  auto begin() const { return vec.cbegin(); }
  auto end() const { return vec.cend(); }
  auto size() const { return vec.size(); }
};

namespace std::ranges
{
  template <typename T>
  auto begin(Foo<T>& x) { return x.begin(); }
  template <typename T>
  auto end(Foo<T>& x) { return x.end(); }
  template <typename T>
  auto begin(const Foo<T>& x) { return x.begin(); }
  template <typename T>
  auto end(const Foo<T>& x) { return x.end(); }
}

template <std::ranges::range range>
void some_algorithm(const range& r)
{
    return std::accumulate(std::ranges::begin(r), std::ranges::end(r), 0);
}

int main()
{
}

我收到一条错误消息:

include/vector.h:93:78: error: reference to 'end' is ambiguous
   93 |     return std::sqrt(std::accumulate(std::ranges::begin(range), std::ranges::end(range), 0));
      |                                                                              ^~~
In file included from c:\mingw64\include\c++\10.2.0\string:54,
                 from c:\mingw64\include\c++\10.2.0\bits\locale_classes.h:40,
                 from c:\mingw64\include\c++\10.2.0\bits\ios_base.h:41,
                 from c:\mingw64\include\c++\10.2.0\ios:42,
                 from c:\mingw64\include\c++\10.2.0\ostream:38,
                 from c:\mingw64\include\c++\10.2.0\iostream:39,
                 from main.cpp:1:
c:\mingw64\include\c++\10.2.0\bits\range_access.h:846:42: note: candidates are: 'constexpr const std::ranges::__cust_access::_End std::ranges::__cust::end'
  846 |     inline constexpr __cust_access::_End end{};
      |                                          ^~~
In file included from main.cpp:8:
include/vector.h:71:8: note:                 'template<class T, long long unsigned int N> auto std::ranges::end(const vec<T, N>&)'
   71 |   auto end(const vec<T, N>& v)

“开始”也是如此。我知道错误消息的含义,但我真的不明白为什么会这样。我什至不启动模板,那它为什么还要检查呼叫呢?我有点迷茫,谁能帮帮我?

【问题讨论】:

    标签: c++ c++20 c++-concepts std-ranges


    【解决方案1】:

    std::ranges::begin 不是函数;它是一个函数对象。你不能专门化它或重新定义它。这是故意的

    std 命名空间中专门化 begin/end 的旧标准方法不是 Ranges 的工作方式,它的设计专门阻止您这样做。创建范围的方法是定义成员 begin/end 函数或在范围类型的命名空间中定义支持 ADL 的 begin/end 函数。

    同样,愚蠢的using std::begin; begin(rng); 习语不是你调用ranges::begin 的方式。您可以通过...调用std::ranges::begin 来调用它。因为这就是你应该调用函数的方式。

    【讨论】:

      猜你喜欢
      • 2019-12-22
      • 2011-07-28
      • 1970-01-01
      • 2022-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-20
      • 2010-11-22
      相关资源
      最近更新 更多