【发布时间】:2020-12-30 21:38:04
【问题描述】:
我正在尝试创建一个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
::map[with T=Option ]' 的实例与参数列表匹配
是否有特定的解决方法,或者我每次调用map() 函数时都必须声明函数?
【问题讨论】:
-
C++ 惯用地图称为
std::transform,顺便说一句。 -
您应该查看
auto返回类型和type_traits库,尤其是std::invoke_result -
S 仅用于方法。我的目的是澄清 List 类型可能与调用该方法的列表的类型不同。我仍然习惯于 C++(我更习惯于 Scala),所以这就是我的心态。此外,查看 std::transform (en.cppreference.com/w/cpp/algorithm/transform) 似乎它直接改变了被调用的值。我的目标是坚持功能范式,因此该方法旨在一起返回一个新列表,而不是更改列表本身。
-
@GLGuy
std::transform(input.begin(), input.end(), std::back_inserter(output), function)是一个东西。还有transform_view,C++20 中的新功能,它与旧的 C++ 做事方式有很大不同,但你应该更熟悉。
标签: c++ list dictionary templates lambda