【发布时间】:2014-04-10 22:42:35
【问题描述】:
我有一些代码可以在 C++ 中编译并正常工作(只要我转发声明通用模板类,然后是专用实例,然后定义通用模板类 - 请参阅 inheriting from class of specialized self?)。但是,当我尝试使用 SWIG 将 C# 绑定添加到类时,它要么使 SWIG 崩溃,要么不包含继承类中的方法。我相信这只能在 C++11 中实现,但我不确定,因为我没有用旧的编译器尝试过。
这是一个玩具示例:
template <typename T, int N = 0> class A;
template <typename T> class A<T, 0>
{
public:
A() : mFoo(NULL) {}
virtual ~A() {}
T* getFoo() { return mFoo; }
protected:
T* mFoo;
};
template <typename T, int N = 0> class A : public A<T, 0>
{
public:
A() : A<T, 0>(), mBar(N) {}
virtual ~A() {}
int getBar() const { return mBar; }
protected:
int mBar;
};
然后在程序中,我可以实例化A<char,10> 的实例(例如),并且可以访问mFoo 和mBar,或者只是实例化A 的实例并且只能访问mFoo。我也可以使用带有参数的方法,例如
void baz(A<T, 0>* anyA)
并且该方法将接受A<T, 0> 或A<T, n> 实例。
对于上下文和解释,此模式适用于动态或固定大小的容器。如果它们是动态的,您可以将其实例化为 A<T, 0> 而没有继承等开销,或者您可以拥有一个使用继承但具有固定大小的容器 (A<T, N> 其中 N > 0)访问所有“基”类方法,可以根据需要覆盖它们,并且仍然可以作为接受容器的动态或固定大小实例的方法的参数。
但是,当我尝试使用 SWIG 以便可以在其他语言中使用此类时,我遇到了问题。
起初,我尝试了类似的方法:
%template(tA) A<char, 0>;
但这会导致 SWIG 崩溃(至少在我当前使用的 3.0.0 版本中)。
接下来,我想,就像 SWIG 中的所有模板继承一样,我需要为基类和继承类拥有一个现有模板(如果两者都被模板化)。所以我尝试了
%template(tABase) A<char, 0>;
%template(tA) A<char>;
这也会导致 SWIG 崩溃。
所以,我尝试变得聪明一点,利用 SWIGS 的能力为继承自的类使用“无名”模板并执行以下操作:
%template() A<char, 0>;
%template(tA) A<char>;
这避免了崩溃,我得到了 tA 类的输出,但它只有来自继承类 A<T, N> 的方法等,实际上并没有从它需要的 A<char, 0> 专用模板实例继承因此我无法访问A<char, 0> 的“基”类中的所有方法和数据。
有没有其他人试图让 SWIG 来处理这个问题?成功地?是否有我可以传递给 SWIG 的命令行参数来使事情正常运行(并阻止它崩溃)?
【问题讨论】:
标签: c++ inheritance c++11 swig template-specialization