我有 100 个左右的蹦床函数。我想知道是否可以将每个都自动包装在 try/catch 块中。
请提前警告,这不是一个简单的问题。我将首先用(简化的)代码描述问题,然后尝试在下面尽力回答它,以便读者可以看到我所处的位置。
Foo 有一个函数指针表:
EDIT: 这是一个C函数指针桌子。所以它可以接受static W::w
.
签名在这里:http://svn.python.org/projects/python/trunk/Include/object.h http://svn.python.org/projects/python/trunk/Include/object.h
编辑:我尝试过一个测试用例here http://coliru.stacked-crooked.com/a/4ede9f86be872ac7:
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;}
}
我正在尝试使用 lambda 来完成此操作,以便绕过必须定义所有这些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)
trap 的定义可能如下所示:
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 允许可变参数。
那么如果这确实有效的话,它可以被清理掉吗?
我的想法是:
1) 也许...应该作为一个包移回模板参数。
2)也许可以推导出trap的返回类型,并保存一个模板参数
3) that Base::Func
模板参数是非法语法。我怀疑这根本不是什么合法的事情。这可能会破坏整个方法。