处理来自 SWIG 中自身专用实例的类继承
Handling class inheritance from specialized instance of self in SWIG
我有一些代码可以在C++中编译和工作正常(只要我转发声明通用模板类,然后声明专用实例,然后定义通用模板类 - 请参阅从专业自我类继承? 但是,当我尝试使用 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++内更花哨
:template<typename T>
struct A0_impl;
template<typename T, typename N>
struct A_impl;
template<typename T, int N>
struct A_helper {
typedef A_impl<T,N> type;
};
template<typename T>
struct A_helper<T,0> {
typedef A0_impl<T> type;
};
template<typename T, int N=0>
using A = typename A_helper<T,N>::type;
template<typename T>
struct A0_impl {
A0_impl() : mFoo(nullptr) {}
virtual ~A0_impl() {}
T* getFoo() { return mFoo; }
private:
T* mFoo;
};
template<typename T, typename N>
struct A_impl:A0_impl<T> {
A_impl() : A0_impl<T>(), mBar(N) {}
virtual ~A_impl() {}
int getBar() const { return mBar; }
protected:
int mBar;
};
template<typename T>
struct A_impl<T,0>:A0_impl<T> {
A_impl() : A0_impl<T>() {}
virtual ~A_impl() {}
// possibly inherit other constructors from A0_impl
};
这为您提供了C++代码,其行为与您的版本几乎完全相同,但消除了您认为导致问题的专用化后裔问题。
基本上,我用A0_impl
替换了您的A<T,0>
专用化,并且template
别名A<T,N>
现在映射到A_impl<T,N>
或A0_impl<T>
,具体取决于N
是否0
。
A
template
别名是可选的,因为您可以改为A0_impl
被称为AnySizedA
并A_impl
被称为 FixedSizeA
,而不是专门A<T,0>
做某事,只需禁止它。
- 静态数据成员模板专用化的实例化点在哪里
- 您能否实例化模板的非专用版本并在专用化中继承它?
- 如果专用化已经隐式实例化,它是否隐式实例化?
- DLLexport 类模板实例(专用化),减少了仅标头模板库的编译时间
- 在 Xcode 中实例化后的显式专用化
- 是具有接口专用化的子类多态的模板实例化
- 在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗
- 选择专用于派生实例的基类的类模板
- 在模板中,有没有办法为每个时间实例化只编写一个专用化?(纳秒、毫秒、秒等)
- 错误 C2908:显式专用化; 已被实例化
- 一种安全、符合标准的方法,使类模板专用化仅在实例化时才无法使用"static_assert"进行编译
- 对实例化和未实例化模板的部分模板专用化
- 模板类方法的部分专用化或实例化
- 如何将包装作为模板参数实例化专用模板类
- 共享库:具有部分模板专用化和显式模板实例化的未定义引用
- 模板专用化的实例化不正确
- 完整的模板专用化不起作用:没有与指定类型匹配的函数模板"mysort2"实例 STLests
- MSVC 编译器实例化函数模板的默认定义,即使存在专用化
- 声明无法解决"实例化后的显式专用化"错误
- 如何为模板类的所有实例专用化或重载全局模板函数