任意の型のメソッドへのポインターを受け取るテンプレート メソッドがあるとします。void(A::*)()
そのテンプレート内で、メソッド ポインター型 (たとえば) であるテンプレート引数を、同じ戻り値の型とパラメーターを持つ関数ポインター型に変換する方法はありますが、クラス情報はありません ( void(*)()
)?
ヘッダーを見ました<type_traits>
が、役立つものは見つかりませんでした。
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
メンバー関数(および理論的にはref修飾された関数も)には、個別の部分的な特殊化が必要であることに注意してください。
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( )を使用すると、 †</sup>を提供するため{nil, &, &&}
の部分的な特殊化の合計があります。通常、修飾を省略して、合計を「ちょうど」6に減らすことができます。ほとんどのコンパイラはfunction-ref-qualifierをサポートしていないため、実際に必要なのは2つだけですが、残りは注意してください。2*2*3 == 12
volatile
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-qualifiersでは完全には機能しませんが、C ++ 03では、R(Args...) const
部分的に特殊化して.を削除できるcv-qualified署名(例)は許可されていなかったと思いますconst
。
†{...}
は、特定の修飾子のセットをnil
示し、空のセットを表します。例:
void f() const&
だろう{const}, {nil}, {&}
void f() &&
だろう{nil}, {nil}, {&&}
等々。