是否存在range :: view :: transform的可修改视图版本? [英] Is there a modifiable-view version of ranges::view::transform?

查看:76
本文介绍了是否存在range :: view :: transform的可修改视图版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下程序:

#include <iostream>
#include <algorithm>
#include <numeric>
#include <array>
#include <range/v3/view/transform.hpp>

int main() {
    using container = std::array<std::tuple<int,float,double>, 4>;
    container tuples {{
        {1, 4.f, 8.},
        {2, 5.f, 9.},
        {3, 6.f, 10.},
        {4, 7.f, 11.}
    }};

    auto int_view =
        tuples | ranges::view::transform( [](auto& t){return std::get<int>(t);} );

    // int_view[1] = 3; // (*)

    auto x = std::accumulate(int_view.begin(), int_view.end(), 0);
    std::cout << "x = " << x << std::endl;
}

这将编译并打印10;但是-如果我取消注释(*)行-它不会编译,GCC抱怨等式的左侧不是左值.我对此感到失望-我有点希望转换会产生int&,我可以将其分配给...

This compiles and prints 10; but - if I uncomment the (*) line - it doesn't compile, with GCC complaining about the left side of the equality not being an lvalue. I was kind of disappointed by that - I was sort of hoping the transformation would produce int&'s which I could assign to...

我可以做些修改吗?还是Ranges库中的某些其他机制可以使我获得等同于可修改视图的功能?

Is there something I can to make this a modifiable view? Or some other mechanism in the ranges library which would allow me the equivalent of a modifiable view?

推荐答案

如果考虑一下,代码的问题很简单:

The problem with your code is very simple, if you think about it:

变换功能实际上是投影功能,您不会产生允许修改源代码所需的引用,因为

The transformation-function is actually a projection-function, and yours doesn't produce the references necessary for allowing modification of the source, because the standard return type deduction rule for lambdas uses the rules for plain auto, and those never deduce references.

  1. 一个解决方案正在更改decltype(auto) 的扣除规则,它保留了引用,因此最好避免使用,除非您知道它们是正确的.

auto int_view = tuples | ranges::view::transform(
    [](auto& t)->decltype(auto){return std::get<int>(t);});

  • 或者您可以使用auto&或更具体的内容来明确要求引用.

  • Or you can explicitly ask for references with auto& or something more specific.

    auto int_view = tuples | ranges::view::transform(
        [](auto& t)->auto&{return std::get<int>(t);});
    

  • 最后,没有人阻止您返回像std::reference_wrapper这样的代理.虽然这是不必要的并发症.

  • And finally nobody stops you from returning a proxy like std::reference_wrapper. Though that's a needless complication.

    auto int_view = tuples | ranges::view::transform(
        [](auto& t){return std::ref(std::get<int>(t));});
    

  • 这篇关于是否存在range :: view :: transform的可修改视图版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆