考虑一个模板类,如:
template<typename ReturnType, ReturnType Fn()>
class Proxy
{
void run()
{
ReturnType ret = Fn();
// ... do something ...
}
};
// and a functions
int fn1() { return 5; }
float fn2() { return 5; }
这可以通过使用:
来实例化Proxy<int, &fn1> p1;
但明确声明返回值类型似乎是不必要的。我想要实现的是:
someProxyInstantation<&fn1> p1;
someProxyInstantation<&fn2> p2;
不幸的是,我不是c ++的期望,这似乎是语言的一个隐藏角落(至少对我而言)。
如果我可以从指向函数的指针到它的类型 - 例如: std :: tr1 :: result_of&lt;&amp; fn&gt; :: type //错误1错误C2923:'std :: tr1 :: result_of':'fn1'不是参数'_Fty'的有效模板类型参数
错误有意义,因为参数不是“类型”
C ++ 0x具有decltype(&amp; fn1)但距离它还有几年。
在C ++ 03(+ tr1)中以任何方式执行此操作?
限制: - 我不想传递仿函数,f1和f2必须保留具有返回值的全局函数(不能将其移动到参数)。)
答案 0 :(得分:6)
这在C ++ 03中是不可能的。如果要将函数指针作为非类型参数传递,则编译器必须知道参数的类型。所以你必须提供缺失的部分(在这种情况下,返回类型)。您可以在运行时为代理提供函数指针作为值,并为其提供其类型作为唯一参数。然后你可以为你编写一个生成函数来完成这项工作:
template<typename T>
Proxy<T> make_proxy(T t) { return Proxy<T>(t); }
可悲的是,在当前的C ++中,你仍然必须给它类型才能分配一个自动变量:
Proxy<int(*)()> p = make_proxy(&fn1);
您还不能使用auto p = make_proxy(&fn1);
。请注意,如果要在左侧使用函数类型,则必须更改生成器函数以提供不是函数指针类型:
template<typename T>
Proxy<typename boost::remove_pointer<T>::type> make_proxy(T t) {
return Proxy<typename boost::remove_pointer<T>::type>(t);
}
现在你可以做到
Proxy<int()> p = make_proxy(&fn1);
使用代理,你现在可以做到
doSomething(make_proxy(&fn1));
如果doSomething是模板化的或其他多态的,那么它不需要你知道函数的确切类型。