为什么使用 ADL 时 `std::ranges::size` 需要非常量方法?

zjy*_*qs 7 c++ argument-dependent-lookup c++20 std-ranges

否则,如果 Ranges::disable_sized_range<std::remove_cv_t<T>> 为 false,则 size(t) 转换为其衰减类型,并且转换后的表达式有效且具有类似整数的类型,其中重载解析通过以下命令执行以下候选人:

  • void size(auto&) = delete;
  • void size(const auto&) = delete; 1
class Test {
    friend size_t size(/*const*/ Test&) {
        return 0;
    }
};

int main() {
    std::ranges::size(Test{});
    // no matching function error when adding the `const` qualifier
}
Run Code Online (Sandbox Code Playgroud)

https://godbolt.org/z/79e5vrKrT


一般来说,方法size不需要std::size.

为什么会有这样的限制呢std::ranges::size?(好像只有非会员版才能执行。)

康桓瑋*_*康桓瑋 3

为什么会有这样的限制呢std::ranges::size?(好像只有非会员版才能执行。)

尽管该size方法不修改范围,但某些范围没有const- 限定成员begin(),这仅允许非const- 限定对象对 a 进行建模range

这也使得一些范围适配器在标准中可能只有一个const不合格size

对于您的示例,考虑到Test只有非const begin/endsize,那么friend size_t size(Test&)实际上只能是选项。

  • 但令人惊讶的是,“friend size_t size(const Test&amp;)”不适用于 const 和非 const 对象。它只是因为“void size(auto&amp;) = delete;”重载而对两者都不起作用,如果从实现中删除它,那么它就可以工作。 (2认同)
  • 我们有 [LWG 3480](https://cplusplus.github.io/LWG/issue3480),它也是基于这些毒丸,我们通过更改非成员函数来解决它 - 但也可以通过更换毒丸解决了。 (2认同)