C++ SWIG:公共函数中使用的私有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 导致此错误的包装器代码

我经常给我的类一个私有的typedef来表示它们自己,如下所示:

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文档时,我相信是这样的:你只需要把它公开。