首页 文章

c扣除“非类型指针函数”类模板参数

提问于
浏览
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;

不幸的是,我没有期待,这似乎是语言的隐藏角落(至少对我而言) .

如果我可以从指向函数的指针到它的类型 - 类似于:std :: tr1 :: result_of <&fn> :: type //错误1错误C2923:'std :: tr1 :: result_of':'fn1 '不是参数'_Fty'的有效模板类型参数

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

C 0x具有decltype(&fn1),但距今已有数年 .

Any way of doing this in C++03 (+ tr1)?

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

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

相关问题