operator| 是如何重载的专门实施 C++ 范围适配器?
How is overloaded operator| implemented specifically c++ range adaptors?
自从范围被合并到 C++ 20 中,我一直在查看 headers 以了解 operator|
是如何为范围视图重载的,但我找不到关于如何或如何重载的正确轨道它在哪里实施。
根据 https://en.cppreference.com/w/cpp/ranges,C(R)
等同于 R | C
,基于我所阅读的内容。
或者,V(R, F)
等同于R | V(F)
,其中V
是范围适配器object,R
是可视范围,F
是任何可调用的 object 包括自由函数。
我已经阅读 What are the basic rules and idioms for operator overloading? 并且已经知道如何正确重载运算符,但是我找不到关于需要什么函数参数或模板参数,或者语法含义的指南,来满足上述实施要求。
我的意思不是要替换范围适配器的所有信息,而只是替换它在重载 operator|
.
的适配器范围上的语法特征
还有一个就是管道后得到的object类型必须和容器的类型一样,只要满足下面的概念即可。
我的想法:
template <std::ranges::viewable_range Ran, std::invocable Inv>
auto operator|(Ran cont, Inv func) {
/* ... */
}
一些应用(假设我们已经实现了功能):
std::vector<int> vect1 {10, 3, 5, 3};
auto new_vect1 = vect1 | myfilter([](auto x){ return x % 3 == 0; });
// where new_vect1 is still `std::vector<int>`
其中 myfilter
:
template <std::viewable_range T, std::invocable F>
decltype(auto) myfilter(T container, F func);
但我认为我的想法要么完全错误,要么在某些方面是错误的,其中大部分都被遗漏了。
这是基本结构:
template<std::ranges::viewable_range Range, other_concepts... OtherArgs>
new_range_t my_view(Range range, OtherArgs... args);
template<other_concepts... OtherArgs>
/* some type */ my_view(OtherArgs... args);
template<std::ranges::viewable_range Range, other_concepts... OtherArgs>
new_range_t operator|(Range range, /* some type */ holder);
您可以使用具有两个 operator()
模板的对象来代替一对函数模板。
struct my_view_t {
template<std::ranges::viewable_range Range, other_concepts... OtherArgs>
new_range_t operator()(Range range, OtherArgs... args);
template<other_concepts... OtherArgs>
/* some type */ operator()(OtherArgs... args);
} my_view;
OtherArgs...
可能不是参数包,但它表示您的视图采用的任何其他参数。如果它是一个参数包,你必须确保第二个参数永远不是一个范围,这样 my_view(R, args...)
和 R | my_view(args...)
对于哪个重载就不会模棱两可。
在没有任何其他参数的特定情况下,您可以让一个对象执行双重任务。
struct nullary_view_t {
template<std::ranges::viewable_range Range>
new_range_t operator()(Range range);
template<std::ranges::viewable_range Range>
friend new_range_t operator|(Range range, nullary_view_t);
} nullary_view;
自从范围被合并到 C++ 20 中,我一直在查看 headers 以了解 operator|
是如何为范围视图重载的,但我找不到关于如何或如何重载的正确轨道它在哪里实施。
根据 https://en.cppreference.com/w/cpp/ranges,
C(R)
等同于 R | C
,基于我所阅读的内容。
或者,V(R, F)
等同于R | V(F)
,其中V
是范围适配器object,R
是可视范围,F
是任何可调用的 object 包括自由函数。
我已经阅读 What are the basic rules and idioms for operator overloading? 并且已经知道如何正确重载运算符,但是我找不到关于需要什么函数参数或模板参数,或者语法含义的指南,来满足上述实施要求。
我的意思不是要替换范围适配器的所有信息,而只是替换它在重载 operator|
.
还有一个就是管道后得到的object类型必须和容器的类型一样,只要满足下面的概念即可。
我的想法:
template <std::ranges::viewable_range Ran, std::invocable Inv>
auto operator|(Ran cont, Inv func) {
/* ... */
}
一些应用(假设我们已经实现了功能):
std::vector<int> vect1 {10, 3, 5, 3};
auto new_vect1 = vect1 | myfilter([](auto x){ return x % 3 == 0; });
// where new_vect1 is still `std::vector<int>`
其中 myfilter
:
template <std::viewable_range T, std::invocable F>
decltype(auto) myfilter(T container, F func);
但我认为我的想法要么完全错误,要么在某些方面是错误的,其中大部分都被遗漏了。
这是基本结构:
template<std::ranges::viewable_range Range, other_concepts... OtherArgs>
new_range_t my_view(Range range, OtherArgs... args);
template<other_concepts... OtherArgs>
/* some type */ my_view(OtherArgs... args);
template<std::ranges::viewable_range Range, other_concepts... OtherArgs>
new_range_t operator|(Range range, /* some type */ holder);
您可以使用具有两个 operator()
模板的对象来代替一对函数模板。
struct my_view_t {
template<std::ranges::viewable_range Range, other_concepts... OtherArgs>
new_range_t operator()(Range range, OtherArgs... args);
template<other_concepts... OtherArgs>
/* some type */ operator()(OtherArgs... args);
} my_view;
OtherArgs...
可能不是参数包,但它表示您的视图采用的任何其他参数。如果它是一个参数包,你必须确保第二个参数永远不是一个范围,这样 my_view(R, args...)
和 R | my_view(args...)
对于哪个重载就不会模棱两可。
在没有任何其他参数的特定情况下,您可以让一个对象执行双重任务。
struct nullary_view_t {
template<std::ranges::viewable_range Range>
new_range_t operator()(Range range);
template<std::ranges::viewable_range Range>
friend new_range_t operator|(Range range, nullary_view_t);
} nullary_view;