为什么使用 clang 15 在向量上调用 std::ranges::rotate 会导致“没有匹配的函数调用 '__begin'”错误?

mil*_*ini 4 c++ compiler-bug clang++ c++20

我有以下函数可以旋转 char 向量:

void rotate()
{
    std::ranges::rotate(_right, _right.begin() + 1);
}
Run Code Online (Sandbox Code Playgroud)

_right 定义为:

 std::vector<char> _right;
Run Code Online (Sandbox Code Playgroud)

尝试用 clang 15 编译它,它抱怨(https://godbolt.org/z/7ovTfxe31):

 no matching function for call to '__begin'
Run Code Online (Sandbox Code Playgroud)

原因似乎如下:

in instantiation of template type alias 'iterator_t' requested here
  requires contiguous_iterator<iterator_t<_Derived>>
Run Code Online (Sandbox Code Playgroud)

但我假设向量是一个连续的容器。代码使用 GCC 编译并运行。

这是我的问题:

  1. 根据cppreference,上述调用应该是合法的调用,还是我错过了什么?
  2. 如果这是一个合法的调用,那么有什么方法可以让 clang 像 GCC 一样接受调用呢?

Jan*_*tke 7

clang 15 及更早版本的编译器在编译 libstdc++ 算法时存在问题,原因在于检查约束是否满足的方式。

请参阅LLVM Issue 44178:[概念] 延迟替换为未实现的类模板成员的要求。这是一个已知的错误,已在 clang 16 中解决。

与 GCC 不同,clang 不会将成员约束的实例化推迟到成员实例化为止。在libstdc++__begin中,尽管显然有一个成员,但从向量创建的__member_begin对象不满足约束。结果就是无法调用。std::subrangestd::rotatestd::subrange.begin()std::rotate