c++ - 为什么 ranges::view_interface<T>::size 需要移动构造函数

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

我不明白搬家的要求从何而来。我在 forward_rangesized_sentinel 中找不到它... 基本示例:


    #include <ranges>
    #include <string>
    #include <iostream>
    
    class vrange: public std::ranges::view_interface<vrange>
    {
        public:
            vrange(std::string &d): data(d){;};
    
            vrange(const vrange &&) = delete;
    
            auto begin() const noexcept { return data.begin(); };
            auto end() const noexcept { return data.end(); };
    
        private:
            std::string data;
    };
    
    int main(){
        std::string h("Hello world");
        vrange r(h);
    
        std::cout << r.size() << std::endl;
        for (const auto &i: r){
            std::cout << i;
            }
        std::cout << std::endl;
        
    
    }

删除对 r.size() 的调用,或默认 vrange 移动构造函数和赋值运算符使其编译正常。

编译器信息:

/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h: In instantiation of ‘constexpr _Derived& std::ranges::view_interface<_Derived>::_M_derived() [with _Derived = vrange]’:
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h:101:35:   required from ‘constexpr bool std::ranges::view_interface<_Derived>::empty() requires  forward_range<_Derived> [with _Derived = vrange]’
w.cpp:25:12:   required from here
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h:70:23: error: static assertion failed
   70 |         static_assert(view<_Derived>);
      |                       ^~~~~~~~~~~~~~
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h:70:23: note: constraints not satisfied
In file included from /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/ranges:37:
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:136:13:   required for the satisfaction of ‘constructible_from<_Tp, _Tp>’ [with _Tp = vrange]
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:150:13:   required for the satisfaction of ‘move_constructible<_Tp>’ [with _Tp = vrange]
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:247:13:   required for the satisfaction of ‘movable<_Tp>’ [with _Tp = vrange]
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:137:30: note: the expression ‘is_constructible_v<_Tp, _Args ...> [with _Tp = vrange; _Args = {vrange}]’ evaluated to ‘false’
  137 |       = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;

最佳答案

这与size无关具体来说。

view_interface用于构建作为 View 的类型。嗯,the ranges::view concept 要求该类型至少是可移动的。和 view_interface有一个very specific requirement on the type given as its template argument :

Before any member of the resulting specialization of view_interface other than special member functions is referenced, D shall be complete, and model both derived_from<view_interface<D>> and view.

好吧,你的类型没有模型 view因为它是不可移动的。所以你违反了规则,因此你得到了未定义的行为。这可能包括如果您调用某些成员而不调用其他成员时发生的编译错误。

关于c++ - 为什么 ranges::view_interface<T>::size 需要移动构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74269551/

相关文章:

C++ 查找 co_await 等待结果类型

c++ - 为什么Boost.Concept通过空指针调用析构函数?

c++ - 使用 nvcc 的可执行文件比使用 gcc/g++ 和 OpenCL 的要大

c++ - CURLOPT_POSTFIELDS 以奇怪的编码发送数据?

c++ - 是否有必要在 std::coroutine_handle 上调用 destroy?

c++ - boost 概念检查 operator() 重载

C++概念不好用?

c++ - boost 正则表达式链接 : Can't find library

c++ - 当我悬停在 qt 中的不同按钮上时如何更改标签文本?

c++ - 在 C++20 中将多个范围适配器连接成一个范围