の種類は以下の、最小限の例を考えてみましょう:型消去およびテンプレートメソッドパターン
struct S {
using func_t = void(*)(void *);
template<typename T>
static void proto(void *ptr) {
static_cast<T*>(ptr)->f();
}
func_t func;
void *ptr;
};
struct T {
void f() {}
};
void g(S &s) {
s.func(s.ptr);
}
int main() {
T t;
S s;
s.func = &S::proto<T>;
s.ptr = &t;
g(s);
}
かなり明白なアイデアは、それが可能なだけでなく、オブジェクト(のようなT
の束のタイプを消去することです型)を使用してS
のインスタンスの配列を作成し、その配列を反復処理して、所定のメンバ関数を呼び出します。
これまでのところ非常に優れているため、実装が簡単で動作します。
template<typename T, typename F>
static void proto(void *ptr, F &&f) {
auto *t = static_cast<T*>(ptr);
std::forward<F>(f)(*t);
t->f();
}
またはこの:
template<typename T>
static void proto(void *ptr, void(*f)(T &)) {
auto *t = static_cast<T*>(ptr);
f(*t);
t->f();
}
は次のように呼び出される:
今私は、消去対象に呼び出される外部関数を提供するために、このようなものだ何かをしたいと思います
s.func(s.ptr, [](auto obj){ /* ... */ });
派生クラスの代わりに呼び出し元によって追加の機能が提供される一種のテンプレートメソッドパターン。
私は、特殊化を均等にして関数ポインタに割り当てることができないため、残念ながらそれはできません。
私が見ることができる唯一の選択肢は、以下のいずれかのようにカスタムクラスを定義することです:
何とかf
派遣右のメンバ関数への内部呼び出しは、その後、としてそれを使用
struct C {
template<typename T>
void f(T &t) { /* ... */ }
// ...
};
:
struct S {
using func_t = void(*)(void *, C &);
template<typename T>
static void proto(void *ptr, C &c) {
auto t = static_cast<T*>(ptr);
c.f(*t);
t->f();
}
func_t func;
void *ptr;
};
これは、ラムダを使用することによって、それほど遠くはありませんが、より冗長で、明示的にクラスを宣言する必要があります。C
これを実現する他の有効な方法はありますか、これが唯一実行可能な解決策ですか?
私は[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)を感じます。サポートしているテンプレートマジックが完璧に動作していると仮定して記述したいコードを教えてください。 – nwp
@nwp私は何か似たものを与えました。想像してみれば、私は 's.ptunc(s.ptr、[](auto obj){/ * ... * /});'を呼び出すことを繰り返しています。わずかに異なるラムダを持つ時間。詳細を教えてもらえますか?私はそれをどのように説明するか分からない_より。ごめんなさい。 – skypjack
配列内のすべての要素の共通点は何ですか?彼らは単に共通のメンバ関数 'void f()'を持っていますか? – nwp