使用c 11构造映射函数

两者都教我自己实现更高级的模板结构而不仅仅是基本的模板结构,并且因为它们在许多情况下都很有用,我正在尝试使用像decltype这样的c 11结构来实现函数式编程中常见的map,filter和类似函数.

我在创建我使用的编译器可以处理的函数原型时遇到了麻烦,所以我不得不问你如何创建这样的东西:

//
// Takes an iterable,applies a function to every element,and returns a vector of the results
//
template <typename T,typename Func>
auto map(const T& iterable,Func func) -> std::vector< decltype(  func( *iterable.cbegin() ) ) >
{
    // body snipped
}

也就是说,此函数应该采用任何iterable和一个函数,该函数将iterables值类型作为参数并返回某种值.函数调用的结果将是传递函数返回的类型的向量,无论传入的可迭代类型如何.

map函数应接受任何具有有效原型作为参数的函数,无论它是函数指针,函子还是lambda表达式.

使用上面的函数与此测试代码

std::vector<int> intVector;
intVector.push_back(1);
intVector.push_back(2);

map(intVector,[](int& value) { return value + 1; });

使visual studio吐出C2893(“专业化功能模板失败”)错误,我不确定是什么问题.

更新:
到目前为止,在评论和答案中建议应用的更改,新的原型测试但仍然存在相同的错误.

解决方法

这可能会做你想要的.它在内部使用std :: transform,它基本上完成了整个工作.我写的函数只不过是一个简单的容器包装器(不使用C风格的数组,需要一些额外的类型特性):
#include <vector>
#include <algorithm>
#include <type_traits>

//
// Takes an iterable,// and returns a vector of the results
//
template <typename T,typename Func>
auto map_container(const T& iterable,Func&& func) ->
    std::vector<decltype(func(std::declval<typename T::value_type>()))>
{
    // Some convenience type deFinitions
    typedef decltype(func(std::declval<typename T::value_type>())) value_type;
    typedef std::vector<value_type> result_type;

    // Prepares an output vector of the appropriate size
    result_type res(iterable.size());

    // Let std::transform apply `func` to all elements
    // (use perfect forwarding for the function object)
    std::transform(
        begin(iterable),end(iterable),res.begin(),std::forward<Func>(func)
        );

    return res;
}

但是,请注意你的lambda应该引用const,或者更好的是在int的情况下应该通过value来获取它的参数.

此外,我将函数从map重命名为map_container:对于函数,变量或程序中的任何其他内容,重用C标准库的标准容器名称是一种错误的编程习惯.

对我来说,这给出了所需的输出

#include <iostream>

int main()
{
    std::vector<int> intVector;

    intVector.push_back(1);
    intVector.push_back(2);

    auto v = map_container(intVector,[] (int value) { return value + 1; });

    for (int i : v) { std::cout << i << " "; }
}

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...