2008-12-15 165 views
4

考虑一个模板类,如:C++“非类型函数指针”类模板的推演参数

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 < & FN> :: //类型错误1错误C2923:“的std :: TR1: :的result_of”:‘FN1’不是参数的有效模板类型参数‘_Fty’

错误有道理的,因为该参数是不是一个‘类型’的所有

的C++ 0x有decltype( & fn1)但那是几年。

在C++ 03(+ tr1)中这样做的任何方式?

限制: - 我不想通过函子,F1和F2必须保持有返回值全局函数(无法将其迁移至参数))

回答

6

这ISN”。 t可能在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的是模板化或以其他方式多态的,它不会要求您知道该功能的确切类型。

+0

直到C++ 0x这将不得不这样做。 – 2008-12-16 00:06:59