【问题标题】:convenience function/macro for std::transformstd::transform 的便利函数/宏
【发布时间】: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 听起来不错。关于如何实现这一点的任何提示?

标签: c++ templates macros


【解决方案1】:

你可以这样做:

// helper class to rebind a container to use an other type
template<typename Container, typename T> struct rebind;

// specialization for vector
template <typename Tc, typename A, typename T>
struct rebind<std::vector<Tc, A>, T>
{
    using type = std::vector<T, typename A::template rebind<T>::other>;
};

还有你的方法

template<
    typename F,
    typename C,
    typename ContainerOut =
        typename rebind<C, decltype(std::declval<F>()(*std::begin(std::declval<C>())))>::type
    >
ContainerOut
 mapp(F f, const C& c)
{
    ContainerOut res;
    res.reserve(c.size());
    std::transform(std::begin(c), std::end(c), std::back_inserter(res), f);
    return res;
}

Live example

【讨论】:

    猜你喜欢
    • 2016-04-22
    • 2011-10-31
    • 2021-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多