![](/img/trans.png)
[英]Can ranges::equal be used as a predicate for a pair of transform_view ranges?
[英]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
的規則 ,而那些從不推斷引用。
一個修復是更改為decltype(auto)
的扣除規則 ,它保留了引用,因此除非您知道它們是正確的,否則可以更好地避免。
auto int_view = tuples | ranges::view::transform( [](auto& t)->decltype(auto){return std::get<int>(t);});
或者您可以明確要求使用auto&
或更具體的引用。
auto int_view = tuples | ranges::view::transform( [](auto& t)->auto&{return std::get<int>(t);});
最后沒有人阻止你返回像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.