我有以下模板功能:
template<class T, class F> T function(F& f) {
...
T t;
f(t);
return t;
}
预计将与F一起使用,格式为
void some_function(SomeType& s);
以这种方式
function<SomeType>(some_function);
第一个模板参数似乎是多余的,因为可以从参数函数的参数中推断出来。 问题是 是否存在摆脱第一个模板参数的方法?
像
这样的东西template<class F> first_param_type<F> function(F& f) {
...
first_param_type<F> t;
f(t);
return t;
}
因此我可以将其用作
function(some_function);
答案 0 :(得分:3)
template<class T>
T function( void(*f)(T&) ) {
...
T t;
f(t);
return t;
}
解决了所述的问题。一般问题无法解决(F
是任意可调用的),因为C ++中的callable可以接受多种类型,并且在一般情况下无法解决可接受的类型。
如果你有一个你支持的类型列表,那么通常可以解决它。
C ++ 14中的基本问题是function([](auto&x){ std::cout << x << '\n'; })
。 C ++ 11中存在同样的问题,其中函数对象具有模板operator()
。 C ++ 14支持自动lambda这一事实意味着这些对象将来会变得越来越普遍。
请考虑更改您的设计,以使F
的签名为T()
而不是void(T&)
。然后我们得到:
template<class F>
std::result_of_t<F()>
function( F&& f ) {
...
return std::forward<F>(f)();
}
C ++ 11中的或typename std::result_of<F()>::type
。
答案 1 :(得分:0)
我希望我理解你的问题,也许我错了......
首先,我希望你的模板函数必须被调用,而对于调用,它需要我在示例代码中找不到的其他参数。
但是,我希望你能做些什么:
#include <iostream>
using namespace std;
template <typename RetType, typename ... Parms>
auto TemplateFunction ( RetType(*ptr)(Parms ...), Parms ... parms ) -> RetType
{
RetType ret;
ret = (*ptr)( parms...);
cout << "Value ret in Wrapper is:" << ret << endl;
return ret;
}
double AnyFunc(int a, int b) { return 3.14 * a + b; }
std::string OtherFunc( ) { return "Hallo"; }
int main()
{
double result = TemplateFunction(&AnyFunc, 1,3);
cout << "Result is " << result << endl;
cout << TemplateFunction(&OtherFunc) << endl;
}
正如您已经提到的,不需要将返回类型作为附加参数,因为它可以在给定的函数指针中的给定类型中找到。
包装器模板适用于所有返回类型,但不适用于void
!
答案 2 :(得分:0)
更新
我绝对同意Yakk的回答我只是想提一下其他但非常相似的方式:
#include <functional>
template < class Type >
Type myFunction( const std::function< void( Type& ) >& aFunction )
{
Type instance;
aFunction( instance );
return instance;
}