是否有范围::视图::转换的可修改视图版本
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&
我可以分配给......
我能做些什么来使它成为一个可修改的视图吗?或者范围库中的其他一些机制可以让我等效于可修改的视图?
如果你考虑一下,你的代码的问题非常简单:
转换函数实际上是一个投影函数,你的函数不会产生允许修改源所需的引用,因为 lambda 的标准返回类型推导规则使用普通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));});
相关文章:
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 视图中的参数推导失败:take_while
- 独立读取-修改-写入顺序
- 当系统的卷被修改时,如何修改WASAPI环回捕获卷
- 修改函数中的指针(将另一个指针作为参数传递)
- 为什么我可以通过引用修改常量返回
- 对于结构,表达式必须是可修改的ivalue
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 为什么不能修改对象中的值?另外,我如何改进此链表?
- 如何维护资源管理器项目视图中当前可见的项目列表
- 修改创建帐户程序
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 如何从子成员函数修改父公共成员变量
- 修改 VS Code 中的默认C++代码段
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 修改"参数视图属性"面板 (5.7.0) 上的默认属性
- 从固定函数迁移到 GLSL OpenGL:我应该如何修改我的视图(lookAt)矩阵和透视矩阵?
- 是否有范围::视图::转换的可修改视图版本
- Finder列视图修改活动列的宽度