2

Suppose you have template method that takes a pointer to a method of any type. Inside that template, is there a way to turn the template argument, which is a method pointer type (void(A::*)() for example), into a function pointer type with the same return type and parameters, but without the class information (void(*)())?

I looked at the <type_traits> header but didn't find anything that would help.

4

1 回答 1

4

C++11 中的一个简单方法是使用可变参数模板进行部分特化:

template<class PMF> struct pmf_to_pf;

template<class R, class C, class... Args>
struct pmf_to_pf<R (C::*)(Args...)>{
  using type = R(*)(Args...); // I like using aliases
};

请注意,您需要对const成员函数进行单独的部分特化(理论上也需要对具有引用资格的函数):

template<class R, class C, class... Args>
struct pmf_to_pf<R (C::*)(Args...) const>{
  using type = R(*)(Args...);
};

使用 cv-qualifiers ( {nil,const}, {nil,volatile}) 和 ref-qualifiers ( {nil, &, &&}),您总共2*2*3 == 12可以提供部分特化†</sup>。您通常可以省略volatile限定条件,将总数降至“仅” 6 个。由于大多数编译器不支持 function-ref-qualifiers,您实际上只需要 2 个,但请注意其余部分。


对于 C++03(即没有可变参数模板的编译器),您可以使用以下非可变参数形式:

template<class PMF> struct pmf_to_pf;

template<class Sig, class C>
struct pmf_to_pf<Sig C::*>{
  typedef Sig* type; // 'Sig' is 'R(Args...)' and 'Sig*' is 'R(*)(Args...)'
};

尽管这不适用于 cv 限定符,但因为我认为 C++03 不允许 cv 限定签名(例如R(Args...) const),您可以在这些签名上部分专门化以删除const.


{...}表示某个限定词的集合,用nil表示空集。例子:

  • void f() const&将会{const}, {nil}, {&}
  • void f() &&将会{nil}, {nil}, {&&}

等等。

于 2012-12-09T01:00:59.827 回答