这个问题来自 here .然而,之前的问题措辞太糟糕(实际上是错误的),建议我从头开始再问。
我有一张 C 函数指针表。
一些 C 代码(让我们称之为 lib-X)有一个基本的构建 block (让我们称之为 X 对象)。每个 X 对象都可以调用此表上的函数。
这些表函数通常具有不同的签名(参见 typedefs here ),尽管多个函数可以共享相同的签名。表中大约有 100 个这样的函数。
在 C++ 中,每个 X 对象都有一个关联的 Final:Base 类。
我想将这些调用转发给 X 对象的相应 C++ Final 实例,但我想将其包含在 try/catch 中,因为 C++ 使用者可能会提供有问题的 Final。
所以我有一个 C++ 基类,它对表中的每个条目都有一个虚函数。
然后我有一个派生自基类的 C++ Final 类(可能有很多;Final1 Final2 Final3 等)。
所以现在我只需要编写一个处理程序
获取第一个“self”参数(它始终是指向调用该函数的 X 对象的指针)
检索关联的 C++ 基类实例。
在 try catch block 中,调用相应的虚函数,转发所有剩余参数,
... 这将在 Final 中实际调用覆盖。
这有点像试图理解盗梦空间的情节。 lib-X 实际上是 Python 运行时,尽管我试图保持通用性。
问题是有许多这样的函数,这会导致一些非常困惑且难以维护的 C++ 代码——如果我必须为每个函数手动编写一个 trampoline 函数,如下所示:
extern "C" PyObject *call_handler( PyObject *self, PyObject *args, PyObject *kw )
{
try
{
PythonExtensionBase *p = getPythonExtensionBase( self );
if( kw != NULL )
return new_reference_to( p->call( Object(args), :Object(kw) ) );
else
return new_reference_to( p->call( Object(args), Object() ) );
}
catch( Py::Exception & )
{
return NULL; // indicate error
}
}
(来源 here)
我正试图想出一个紧凑的设计来允许这种异常安全的蹦床。
我目前的进度是[已删除,请参阅下面的答案]
最佳答案
是这样的吗?
template<typename RET, class ...Args> // <-- one trap for each f in Base that gets enabled!
RET trap( RET (Base::*f)(Args...), void* self, Args&&...args )
{
try {
auto base = reinterpret_cast<Base*>(self);
return (base->*f)(std::forward<Args>(args)...);
}
catch (...) {
return (RET)0;
}
}
关于c++ - 异常安全蹦床的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27826117/