有没有办法在Range-v3中拥有读写视图?

时间:2019-01-20 06:45:49

标签: c++11 proxy rvalue lvalue range-v3

Range-v3中,可以轻松创建现有容器的视图。例如

#include<range/v3/view/transform.hpp>
#include<cassert>

int main(){
    std::vector<double> v = {1,2,3};
    auto range = v | ranges::v3::view::transform([](auto x){return x*2;});
    assert( range[1] == 4 );
//    range[1] = 4; // error cannot write to an l-value
}

这些视图自然是只读的。 我想知道是否可以通过Range-v3创建读写视图?

我确实知道这种事情比只读要复杂得多,而且并非总是可能,但是我仍然想知道Range-v3中是否有协议可以直接使用它或实现它。

例如,我看到了来自ranges::view_facade的实现成员函数read()的派生类的示例(我再也找不到该示例了,Ranges v3的文档确实分散了)。 write(...)成员函数呢?

我正在寻找一些假设的bi定向transform代码,例如:

#include<range/v3/view/transform.hpp>
#include<cassert>

int main(){
    std::vector<double> v = {1,2,3};
    auto range = v | ranges::v3::view::bitransform([](double x){return x*2;}, [](double x){return x/2;}); // direct and inverse function for read and write
    assert( range[1] == 4 );
    range[1] = 8; // error cannot write to an l-value
    assert( range[1] == 8 );
    assert( v[1] == 4 );
}

1 个答案:

答案 0 :(得分:1)

您可以使transform_view具有代理类型的元素:

#include<vector>
#include<range/v3/view/transform.hpp>
#include<cassert>

struct proxy {
    double& x;
    operator double() { return x*2; }
    void operator=(double y) { x = y / 2; }
};

int main(){
    std::vector<double> v = {1,2,3};
    auto range = v | ranges::v3::view::transform([](auto& x){return proxy{x};});
    assert( range[1] == 4 );
    range[1] = 8;
    assert( range[1] == 8 );
    assert( v[1] == 4 );
}