两者都教我自己实现更高级的模板结构而不仅仅是基本的模板结构,并且因为它们在许多情况下都很有用,我正在尝试使用像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; });
解决方法
这可能会做你想要的.它在内部使用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 << " "; } }