【问题标题】:Is there a way to have read-and-write views in Range-v3?有没有办法在 Range-v3 中拥有读写视图?
【发布时间】:2019-01-20 06:45:49
【问题描述】:

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(...) 成员函数呢?

我正在寻找一些假设的 bidirection 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 );
}

【问题讨论】:

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


    【解决方案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 );
    }
    

    【讨论】:

    • 当然。优秀的。我很惊讶void operator=(double y) 不需要是const。鉴于代理将在此上下文中临时。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-14
    相关资源
    最近更新 更多