我想要一个转换函数,它将一些算法应用于参数并返回转换后的结果。但是,它不一定要更改返回类型,所以我想给调用者提供省略返回类型规范的选项,让编译器从输入类型中推导出它。
(简体)示例:
template <typename Ret = In, typename In, typename Func>
Ret transform(const In& in, Func f)
{
return f(in);
}
我想这样称呼它:
auto result = transform(inValue, transformation); // 1
auto differentResult = transform<DifferentType>(inValue, transformation); // 2
请记住,这是简化的。实际上,我将f
向前传递到std::transform
,In
和Ret
类型是某种容器。因此,我无法使用f
或其他魔法的结果来确定返回类型。当然,提供的示例不起作用,因为这
typename Ret = In, typename In
是非法的。如果我反过来这样做:
typename In, typename Ret = In
它将完全符合我想要的情况1.但是我必须为案例2指定输入类型:
auto differentResult = transform<InType, DifferentType>(inValue, transformation);
这主要是一个方便的问题,如果没有办法,那就这样吧。看来我需要某种尾随模板类型说明符:)
真实代码
template <typename Ret, typename In, typename Func>
Ret transform(const In& input, Func func)
{
Ret output{};
std::transform(std::cbegin(input), std::cend(input), std::inserter(output, std::end(output)), func);
return output;
}
使用上面的表单我总是要指定一个返回类型。我只是想知道如果没有给出input
的模板参数,是否有办法从Ret
推导出它。
编辑:如果我提供两个重载,一个使用2个模板参数,另一个使用3,它可以工作。我仍然想知道是否只能使用一个函数来实现这一点。
答案 0 :(得分:4)
类似于that的东西,带有简单的函数重载:
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
template <typename T>
std::ostream& operator<<( std::ostream& os, std::vector<T> const & vec ) {
for( auto & e : vec )
os << e << " ";
return os;
}
template <typename Ret, typename In, typename Func>
Ret transform_copy( In const& input, Func&& func) {
Ret output{};
std::transform( std::begin(input), std::end(input), std::inserter(output, std::end(output)), std::forward<Func>(func) );
return output;
}
template <typename In, typename Func>
In transform_copy( In const& input, Func&& func) {
return transform_copy<In,In,Func>(input, std::forward<Func>(func));
}
int main() {
std::string str = "abc";
auto r0 = transform_copy( str, [](char b) { return b+1;} );
std::cout << r0 << "\n";
auto r1 = transform_copy<std::vector<int>>( str, [](char b) { return b+1;} );
std::cout << r1 << "\n";
auto r2 = transform_copy<std::string>( r1, [](char b) { return b+1;} );
std::cout << r2 << "\n";
}