c++ - 将列表映射到不同的类型
问题描述
我正在尝试创建一个List
类,主要是因为我想自己实现一些向量不存在的方法。其中之一是一个map()
函数,您可以在其中将 lambda 作为参数传递,并且该方法返回一个新List
的,其中旧列表中的每个值都已传递给该函数。
我遇到的问题是获取方法来处理返回List
具有不同类型的特征。例如:
List<Option<int>> y;
y.append(option(1));
y.append(option(2));
y.append(option(3));
//y is [Option(1), Option(2), Option(3)]
List<int> z = y.map([](Option<int> o) {return o.get();});
//z should be [1,2,3]
函数在map()
其当前状态下定义为:
template<typename S>
List<S> map(S (* function)(T)) {
List<S> output;
for (int i = 0; i < size(); i++) {
output.append(function((*this)[i]));
}
return output;
}
问题是上面似乎不允许我传入一个 lambda,只能传入一个先前定义的函数,这违背了该方法方便的目的。我可以让它接受 lambda 的唯一方法是将函数定义为:
template<typename S, typename R>
List<S> map(R function) {
List<S> output;
for (int i = 0; i < size(); i++) {
output.append(function((*this)[i]));
}
return output;
}
但这导致了一个不同的问题,它说:
没有函数模板 'List<T>::map[with T=Option<int>]' 的实例与参数列表匹配
是否有特定的解决方法,或者我每次调用函数时都必须声明map()
函数?
解决方案
使用decltype
. 在您的定义中,您希望使用函数返回的内容来确定output
列表返回值的类型。所以你可以做这样的事情:
template<typename R>
auto map(R function) {
List<std::decay_t<decltype(function(operator[](0)))>> output;
for(int i = 0; i < size(); i++) output.append(function(operator[](i)));
return output;
}
列表元素的类型是function
在 的元素上调用时返回的任何内容this
。将std::decay_t
您无法存储的类型(引用、cv 限定类型、数组等)转换为您可以存储的类型(分别为非引用、非限定类型、指针等)。
使用 可以实现更强大的结果std::invoke_result
,它允许您将函数调用替换为std::invoke
:
template<typename T>
struct List { // Your list class, we need the T
template<typename R>
auto map(R function) {
List<std::decay_t<std::invoke_result_t<R, T&>>> output; // assuming that accesses give references
for(int i = 0; i < size(); i++) output.append(std::invoke(function, operator[](i)));
return output;
}
};
结果是现在您还可以使用map
指向列表中成员的指针之类的东西。
推荐阅读
- c# - 如何同步执行主题中的功能?
- material-ui - 不再找到 material-ui 中的模块
- android - 如何以编程方式更改 TabItem 可见性?
- python - 如何测试 AVL 树的自定义实现
- gcc - 输入 GCC 的这种显然非标准的结构包装语法是什么?
- entity-framework - Entity Framework Core - 有转换 - 支持空值
- unity3d - 刚体不会停止向后移动
- ios - Swift - 此服务器的证书无效
- php - PHP Array of ex:8 项到 4 项的数组,包含该数组的 2-2 个元素
- javascript - 是否可以仅更改标签中的文本(没有其他元素)?