【发布时间】:2014-08-13 10:57:36
【问题描述】:
为了好玩,我尝试让std::transform 的用法尽可能接近map in Haskell。
我目前的尝试如下,但我想它可以做得更好。
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
template<typename ContainerOut, typename ContainerIn, typename Functor>
ContainerOut mappHelp(const ContainerIn& xs, Functor op)
{
ContainerOut res;
res.reserve(xs.size());
transform(begin(xs), end(xs), back_inserter(res), op);
return res;
}
#define mapp(f, xs, res) mappHelp<decltype(res)>(xs, [](decltype(xs)::value_type it)f);
int main()
{
vector<int> xs = {1,2,3};
// How can we come closer to the following?
// auto ys = mapp({return it * 1.5;}, xs);
vector<double> ys = mapp({return it * 1.5;}, xs, ys);
copy(begin(ys), end(ys), ostream_iterator<double>(std::cout, ","));
}
关于如何避免将返回类型告诉调用(或如何改进它)的任何想法?
【问题讨论】:
-
这太宽泛了。有成千上万种方法可以改进它。
-
一种可能的改进是允许 any 可调用对象作为函数对象,而不是强制使用 lambda。首先,它将使代码向后兼容 C++03,其次,如果您的函数的用户想要小写字符串怎么办?然后将
std::tolower作为参数传递比编写{ return std::tolower(it); }更方便。此更改也不会强制您的函数的用户在 lambdas 中使用预定义的参数名称。 -
如果可能的话,您应该在宏中使用的所有参数周围加上括号。 “摆脱返回类型”是什么意思?
-
因为我似乎获得了接近投票:将这个问题发布在 codereview.stackexchange 上会更好吗?
-
@JoachimPileborg 听起来不错。关于如何实现这一点的任何提示?