1

由于范围被合并到 C++ 20 中,我一直在查看标题以查看operator|范围视图是如何重载的,但我找不到关于如何或在何处实现它的正确轨道。


C(R)根据我所阅读的内容,相当于R | C根据https://en.cppreference.com/w/cpp/ranges 。

或者,V(R, F)等价于R | V(F),其中V是范围适配器对象,R是可查看范围,并且F是包括自由函数在内的任何可调用对象。


我已经阅读了运算符重载的基本规则和习语是什么?并且已经知道如何正确地重载运算符,但是我找不到关于需要哪些函数参数或模板参数或语法含义的指南来满足上述实现的要求。

我的意思不是要替换范围适配器中的所有信息,而只是替换其在具有重载的适配器范围上的语法特征operator|

另一个是管道之后生成的对象类型必须与容器的类型相同,只要它满足以下概念即可。

我的想法:

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);

但我认为我的想法要么完全错误,要么在某些方面是错误的,其中大部分都被遗漏了。

4

1 回答 1

2

这是基本结构:

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;
于 2021-05-26T14:18:05.767 回答