簡體   English   中英

是否有一個可修改的視圖版本的range :: view :: transform?

[英]Is there a modifiable-view version of ranges::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& 's,我可以分配給...

有什么我可以使這個可修改的觀點? 或者范圍庫中的其他一些機制可以讓我相當於一個可修改的視圖?

如果您考慮一下,代碼的問題非常簡單:

轉換函數實際上是一個投影函數,並且你的函數不會產生允許修改源所需的引用,因為lambdas的標准返回類型推導規則使用普通auto規則 ,而那些從不推斷引用。

  1. 一個修復是更改為decltype(auto)的扣除規則 ,它保留了引用,因此除非您知道它們是正確的,否則可以更好地避免。

     auto int_view = tuples | ranges::view::transform( [](auto& t)->decltype(auto){return std::get<int>(t);}); 
  2. 或者您可以明確要求使用auto&或更具體的引用。

     auto int_view = tuples | ranges::view::transform( [](auto& t)->auto&{return std::get<int>(t);}); 
  3. 最后沒有人阻止你返回像std::reference_wrapper這樣的代理。 雖然這是一個不必要的並發症。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM