我有一个自定义的矢量类,对于所有意图和目的,其行为都与std :: vector相似。我想添加一个简单的地图功能:
template <class T> class Vector
{
public:
template<class mapFunction> Vector<typename mapFunction::result_type> map(mapFunction function)
{
Vector<mapFunction::result_type> result(_Length);
for(UINT i = 0; i < _Length; i++)
{
result[i] = function(_Data[i]);
}
return result;
}
...
}
用法:
Vector<int> v(5);
for(int i = 0; i < 5; i++) v[i] = i;
auto mappedVector = v.map(function<double(int)>([](int a) { return a * 2.0; }));
这行得通,但我试图避免需要从lambda表达式强制转换为std::function
。理想情况下,只是v.map([](int a) { return a * 2.0; }));
我意识到我可以编写类似于“ make_pair”的“ make_function”来避免模板参数的需要,但是您仍然需要强制转换所有的lambda。
我将其转换为a,std::function
因为我不知道如何从原始的lambda类型中提取返回类型;因此我正在使用std::function::result_type
。
我以为下面的方法可以工作,但是不能-编译器只是抱怨说它不能推断出“ returnType”的模板参数:
template<class mapFunction, class returnType> Vector<returnType> Map2(mapFunction function)
{
Vector<returnType> result(_Length);
for(UINT i = 0; i < _Length; i++)
{
result[i] = function(_Data[i]);
}
return result;
}
我意识到可以std::transform
做到这一点(我可以轻松地通过调用来替换map的主体std::transform
),但是我的问题确实在于正确地指定模板参数。
首先,不要std::function
用于此类问题。
我先给你一个例子,然后给我一个简短的解释。请注意,我确实使用std::vector
来存储数据并提供功能,因为我真的不想自己实现整个Vector
类;)。
#include <iostream>
#include <vector>
// /---------------------------------------------------------\
// | // |
template<typename T> // |
class Vector { // |
public: // |
std::vector<T> data; // |
// |
template<class mapFunction> // |
// Below: use C++11 trailing return type |
auto map(mapFunction function) -> Vector<decltype(function(std::declval<T>()))>
// | |
{ // | |
// \-----------------------------------/
// |
// |
// /-----------------------------------\
// | |
using ReturnType = decltype(function(std::declval<T>()));
Vector<ReturnType> result;
auto size = data.size();
result.data.reserve(size);
for(std::size_t i = 0; i < size; i++)
{
result.data.push_back(function(data[i]));
}
return result;
}
};
int main() {
Vector<int> v;
for(int i = 0; i < 10; ++i) {
v.data.push_back(i);
}
auto newV = v.map([](int i) -> float {
return (i * 2.0f) + 0.5f; // Multiply by 2 and add 0.5
});
for(auto e : newV.data) {
std::cout << e << std::endl;
}
}
首先,它使用C ++ 11的尾随返回类型功能。需要这样做,因为我们需要引用参数function
。该decltype(function(std::declval<T>()))
部分是一个有趣的部分。基本上,我们要求编译器
“
function
给定类型的参数值的返回类型是T
什么?”
然后,编译器给出返回类型,这就是我们赋予结果的第一个参数的结果Vector
。
后面的部分与您的部分具有相同的本质,尽管我为正确性和优雅性对其进行了修改。
请注意,在C ++ 14中,您可以删除尾随返回类型,然后执行
template<class mapFunction>
auto map(mapFunction function) {
using ReturnType = decltype(function(std::declval<T>()));
Vector<ReturnType> result;
...
return result;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句