C++ SWIG:公共函数中使用的私有typedef
我经常给我的类一个私有的typedef来表示它们自己,如下所示:C++ SWIG:公共函数中使用的私有typedef,c++,typedef,swig,C++,Typedef,Swig,我经常给我的类一个私有的typedef来表示它们自己,如下所示: class MyClass { private: typedef MyClass Self; public: void DeepCopyFrom(const Self& other); ... }; 我现在用SWIG包装我的C++代码,它抱怨这样的类型: error: ‘typedef class MyClass MyClass::Self’ is private 导致此错误的包装器代码
class MyClass {
private:
typedef MyClass Self;
public:
void DeepCopyFrom(const Self& other);
...
};
我现在用SWIG包装我的C++代码,它抱怨这样的类型:
error: ‘typedef class MyClass MyClass::Self’ is private
导致此错误的包装器代码如下所示:
SWIGINTERN PyObject *_wrap_MyClass_DeepCopyFrom(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
MyClass *arg1 = (MyClass *) 0 ;
MyClass::Self *arg2 = 0 ;
(...)
编译器错误发生在省略号上方的最后一行
有没有办法告诉SWIG不要使用私有typedef,而只使用完整的类型名?我建议保持简单(r):只需删除typedef并编写类名即可
如果你真的不喜欢这样,你可以告诉SWIG忽略那些“坏掉的”方法,然后用包装器方法扩展类,调用真正的方法。除非您绑定的类和方法的数量相对于您的总代码库来说很小,否则这种治疗可能比疾病更糟糕。默认情况下,SWIG不会处理任何typedef或声明或
private
部分中的任何内容。因此,它假设(当它看到const Self&
时,Self
是来自报头或其他东西的某个未知类型,它将其保持不变,并生成包装器代码,其中保留了Self
。问题在于此包装器代码是类外部的函数,并且由于MyClass::Self
是私有的,因此编译器会生成一个错误。我的代码也发生了同样的事情:我要做的就是要么在public
部分声明typedef,要么将Self
重写为MyClass
。将typedef更改为public
对我来说最有意义。我很少看到私有的typedef,但我想它在封装方面没有什么问题。但是,如果您有一个使用typedef的公共函数,那么这不就是接口中typedef的一部分吗
我可以想象,您可以在一些成员函数或私有成员函数接口中使用私有typedef。但是如果您想在公共方法上使用它,那么typedef也应该是公共的才有意义
我不知道标准对这个主题有什么规定,但我猜这是为数不多的灰色地带之一。我假设它取决于编译器如何在类中处理typedef的实现,您可以确定在公共方法中使用私有typedef是否可以接受(甚至可以接受)。为了安全起见,我会把它公之于众
如果您担心暴露typedef,那么不要在任何公共成员函数的原型中使用它(这可能会被某些编译器拒绝)。如果您担心名称冲突,请不要这样做,因为任何外部代码都必须用实际的类名解析作用域
我认为您可能对封装的想法有点过分。当您需要不透明类型时,请使用不完整的类(并在实现文件中完成,而不是在头文件中完成)
但在您的特定示例中,我觉得不应该使用不透明类型。为什么不将typedef公开呢?我可以这样做,但我想知道是否有一个SWIG-side解决方案,例如,我可以在.I接口文件中编写一些内容。这部分是因为我不认为“自我”Type是外部接口的一部分。这在一定程度上是为了应对我无法立即更改的代码(例如,其他人的代码)出现这种情况。私有typedef只是公共类型的同义词,所以我认为让公共函数引用它不会破坏封装。正如在中一样,使用它不会公开比我现在更多的类。这个推理不完整吗?我使用的是GCC4.4.3,FWIW。typedef不像define。它与嵌套类或成员函数遵循相同的访问规则。特定的私有typedef是类名的“同义词”这一事实与此无关。用户代码有权访问该类并不意味着它有权访问其私有typedef,即使该typedef代表该类。这就是为什么它应该是公开的。我对你的答案投了赞成票,因为它解释了SWIG land的情况。你说“默认情况下,SWIG不会处理(…)私有部分中的任何内容。”(重点补充。)你知道有没有办法告诉它?@Super:我写“默认”,因为我不确定这是唯一的选择,但在再次查看SWIG文档时,我相信是这样的:你只需要把它公开。