この非コンパイルスニペットを見てみましょう。呼び出しのための便利な構文でメンバー関数ポインタを持つ関数を特殊化することは可能ですか?
struct Object {
template <RETURN (OBJECT::*MEMFN)(PARAMETERS...), typename RETURN, typename OBJECT, typename ...PARAMETERS>
void call() {
}
};
struct Foo {
void fn();
};
int main() {
Object o;
o.call<&Foo::fn>();
}
基本的に、私が達成したいことは呼び出すために便利な構文で、メンバ関数ポインタのいずれかの種類に特化した、機能(Object::call
)を持つことです。
私が見つけた最寄のソリューションは非常に醜いである、このです:
struct Object {
};
template <typename MEMFNTYPE, MEMFNTYPE MEMFN>
struct Caller;
template <typename RETURN, typename OBJECT, typename ...PARAMETERS, RETURN (OBJECT::*MEMFN)(PARAMETERS...)>
struct Caller<RETURN (OBJECT::*)(PARAMETERS...), MEMFN> {
Object *object;
Caller(Object &o) : object(&o) { }
void call() {
// I have the necessary information here: the member function pointer as template parameter, and a pointer to Object
}
};
struct Foo {
void fn();
};
int main() {
Object o;
Caller<decltype(&Foo::fn), &Foo::fn>(o).call();
}
は、この問題のためのよりよい解決策はありますか?
(私はこれをやろうとしているある理由は、私は他のメンバ関数のためのラッパー関数(call
)を作成したいということです)
Kerrek SBがauto
を使用して提案し、私が試してみましたこの:?
struct Object {
template <auto MEMFN>
void call();
template <auto MEMFN, typename RETURN, typename OBJECT, typename ...PARAMETERS>
void call<RETURN (OBJECT::*MEMFN)(PARAMETERS...)>() {
}
};
struct Foo {
void fn();
};
int main() {
Object o;
o.call<&Foo::fn>();
}
しかし、これは(私が(代わりにauto MEMFN
のテンプレートパラメータリストには異なるMEMFN
を追加する必要があります)コンパイルされません:
t2.cpp:6:7: error: parse error in template argument list
void call<RETURN (OBJECT::*MEMFN)(PARAMETERS...)>() {
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
t2.cpp:6:52: error: non-class, non-variable partial specialization ‘call<<expression error> >’ is not allowed
void call<RETURN (OBJECT::*MEMFN)(PARAMETERS...)>() {
'template void call();'を実行してからspecializeします。 –
'std :: bind()'は実際に何をしていませんか? – user0042
'std :: invoke'を求めていますか? http://en.cppreference.com/w/cpp/utility/functional/invoke –