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}, {&&}
等等。