4

考虑一个模板类,如:

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>::type // 错误 1 ​​错误 C2923: 'std::tr1::result_of' : 'fn1 ' 不是参数 '_Fty' 的有效模板类型参数

该错误是有道理的,因为该参数根本不是“类型”

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

在 C++03 (+ tr1) 中有什么方法可以做到这一点?

限制: - 我不想传递函子,f1 和 f2 必须保留具有返回值的全局函数(不能将其移动到参数)。)

4

1 回答 1

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 是模板化的或其他多态的,则不需要您知道函数的确切类型。

于 2008-12-15T15:58:59.707 回答