接受右值引用作为参数的方法的 Swig 行为

Swig behavior for methods that accept rvalue reference as a parameter

Swig 文档指定它有意忽略移动构造函数。但是它没有指定它对接受 rvlaue 引用的方法的作用,例如:

class AAA {
public:
    AAA() {}; // generates java code
    AAA(const AAA& a) {}; // generates java code
    AAA(AAA&& a) {}; // ignored by swig, no java code generated
    virtual void move(const std::string& str); // generates java code
    virtual void move(std::string&& str); // also generates java code, but accepts SWIGTYPE_p_std__string as a parameter instead of String
};

这些方法的行为会有所不同吗?有没有一种在 swig 中使用右值参数的首选方法?还是我不应该使用它们?

通常对于编写良好的 C++ 代码,您会期望两个重载函数或构造函数的相同行为是等效的,但需要注意的是右值引用变体很可能会破坏其输入。

所以为了用另一种语言制作界面,这可能并没有真正 1:1 映射到右值试图表达的概念,那么绝大多数时候正确的答案是简单地忽略这些重载。在某些情况下,在内部,SWIG 生成的包装器可能最终会使用这些重载,或者可以通过您的一些努力来编写,但这只是一种优化。如果您要跨越 JNI 边界,那么这可能不太可能成为您最大的性能瓶颈。 (做任何事情之前都要测量它)。

在某些语言中(例如 Python、Lua?)您可能会想利用这样一个事实,即您的对象是引用计数的,这对您有利,并且(对这些语言来说是透明的)编写一个类型映射如果我们是唯一持有对象引用的人,它会选择使用哪个重载。我认为即使这种情况也是错误的(也是过早的优化),因为:

  1. 如果语言支持这样的构造,则围绕弱引用存在竞争条件。很难发现和避免这种情况。
  2. 即使您只有一个对您的(例如)Python 对象的引用,但仍然可以对同一个 C++ 对象进行多个引用,例如:

    struct a {};
    a& blah() {
      static a a;
      return a;
    }
    

    import test
    a=test.blah()
    b=test.blah()
    c=test.blah()
    

    a、b 和 c 都只有 1 个引用,但移动它们显然是错误的。而且几乎不可能证明什么时候是安全的。

所以我的意思是:除非你别无选择,否则请忽略它们。有时您可能会遇到这样的情况,其中唯一的选择是调用一个接受右值引用的函数。您可以包装这些函数,但需要根据具体情况来完成,因为您需要了解被包装的 function/constructor 的语义。