私は100個ほどのトランポリン機能を持っています。try/catch ブロック内でそれぞれを自動ラップすることが可能かどうかを知りたいです。
簡単な質問ではありませんので、あらかじめご了承ください。まず、(単純化された) コードで問題を説明し、次に、読者がどこにいるのかを理解できるように、以下でできる限り答えようとします。
Foo には関数ポインタ テーブルがあります。
EDIT : これはC 関数のポインタテーブルです。だからそれは受け入れることができましたstatic W::w
。
署名はこちら: http://svn.python.org/projects/python/trunk/Include/object.h
編集:ここでテストケースを試みました:
class Foo {
Table table;
Foo() {
// Each slot has a default lambda.
:
table->fp_53 = [](S s, A a, B b) -> int {cout<<"load me!";};
table->fp_54 = [](S s, C c, D d, E e) -> float {cout<<"load me!";};
// ^ Note: slots MAY have different signatures
// only the first parameter 'S s' is guaranteed
}
// Foo also has a method for loading a particular slot:
:
void load53() { table->fp_53 = func53; }
void load54() { table->fp_54 = func54; }
:
}
特定のスロットが「ロード」されている場合、これはそれにロードされるものです:
int func53(S s, A a, B b) {
try{
return get_base(s)->f53(a,b);
}
catch(...) { return 42;}
}
float func54(S s, C c, D d, E e) {
try{
return get_base(s)->f54(c,d,e);
}
catch(...) { return 3.14;}
}
これらすべてを個別に定義する必要がないように、ラムダを使用してこれを達成しようとしていますfunc53
。このようなもの:
class Foo {
:
void load53() {
table->fp_53 =
[](S s, A a, B b)->int { return get_base(s)->f53(a,b); }
}
void load54() {
table->fp_54 =
[](S s, C c, D d, E e)->float { return get_base(s)->f54(c,d,e); }
}
ただし、これはエラーをトラップできません。return ステートメントの周りに try/catch を配置する必要があります。
try{ return get_base(s)->f53(a,b); } catch{ return 42; }
ただし、これにより多くの混乱が生じます。私ができればいいのですが:
return trap( get_base(s)->f53(a,b); )
trap
私の質問は: この関数を (#define を使用せずに)記述する方法はありますか?
これは私がこれまでに思いついたものです:
これにより、必要なすべての情報が渡されると思います。
trap<int, &Base::f53>(s,a,b)
トラップの定義は次のようになります。
template<typename RET, Base::Func>
static RET
trap(S s, ...) {
try {
return get_base(s)->Func(...);
}
catch {
return std::is_integral<RET>::value ? (RET)(42) : (RET)(3.14);
}
}
これにより、非常にクリーンな構文が可能になる場合があります。
class Foo {
:
void load53() { table->fp_53 = &trap<int, &Base::f53>; }
void load54() { table->fp_54 = &trap<float, &Base::f54>; }
}
現時点では、いくつかの法律が違反されているかどうかさえわかりません。 table->fp_53
有効な C 関数ポインターでなければなりません。
非静的メンバー関数 ( ) のアドレスを渡しても、&Base::f53>
これはテンプレート パラメーターであり、署名には影響しないため、これに違反しません。trap
同様に、...
C では varargs が許可されているので問題ありません。
これが実際に有効である場合、クリーンアップできますか?
私の考えは次のとおりです。
1) おそらく ... をパックとしてテンプレート パラメータに戻す必要があります。
2) トラップの戻り値の型を推測し、1 つのテンプレート パラメータを保存することは可能かもしれません。
3) そのBase::Func
テンプレート パラメータは不正な構文です。そして、それは合法的なものにさえ近づいていないと思います。これは、アプローチ全体を台無しにする可能性があります。