为什么 range::view_interface<T>::size 需要移动构造函数

ser*_*ean 3 c++ c++-concepts c++20 std-ranges

我不明白搬家的要求从何而来。forward_range我在and ...\n基本示例中找不到它sized_sentinel

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

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

\n

编译器消息:

\n
/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h: In instantiation of \xe2\x80\x98constexpr _Derived& std::ranges::view_interface<_Derived>::_M_derived() [with _Derived = vrange]\xe2\x80\x99:\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h:101:35:   required from \xe2\x80\x98constexpr bool std::ranges::view_interface<_Derived>::empty() requires  forward_range<_Derived> [with _Derived = vrange]\xe2\x80\x99\nw.cpp:25:12:   required from here\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h:70:23: error: static assertion failed\n   70 |         static_assert(view<_Derived>);\n      |                       ^~~~~~~~~~~~~~\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/bits/ranges_util.h:70:23: note: constraints not satisfied\nIn file included from /usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/ranges:37:\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:136:13:   required for the satisfaction of \xe2\x80\x98constructible_from<_Tp, _Tp>\xe2\x80\x99 [with _Tp = vrange]\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:150:13:   required for the satisfaction of \xe2\x80\x98move_constructible<_Tp>\xe2\x80\x99 [with _Tp = vrange]\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:247:13:   required for the satisfaction of \xe2\x80\x98movable<_Tp>\xe2\x80\x99 [with _Tp = vrange]\n/usr/lib/gcc/x86_64-pc-linux-gnu/12/include/g++-v12/concepts:137:30: note: the expression \xe2\x80\x98is_constructible_v<_Tp, _Args ...> [with _Tp = vrange; _Args = {vrange}]\xe2\x80\x99 evaluated to \xe2\x80\x98false\xe2\x80\x99\n  137 |       = destructible<_Tp> && is_constructible_v<_Tp, _Args...>;\n
Run Code Online (Sandbox Code Playgroud)\n

Nic*_*las 5

这与具体情况无关size

view_interface用于构建一个类型,即视图。嗯,这个ranges::view概念 要求字体至少是可移动的。并且对其模板参数给出的类型view_interface有非常具体的要求:

view_interface在引用除特殊成员函数之外的结果专业化的任何成员之前,D应是完整的,并且对derived_from<view_interface<D>>和建模view

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