如何在SWIG中包装可变参数模板类的可变参数模板成员函数?

时间:2019-08-14 10:52:43

标签: c++ templates lua variadic-templates swig

我有一个头文件,其中包含可变参数模板的定义,该文件还包含一些可变参数模板化的成员函数。下面的代码段已大大简化,为了简洁起见,将其缩减:

#pragma once

template<typename T, typename ... CtorArgs>
class Foo {
public:
  Foo(CtorArgs... args) : _m(args...) {}

  template<typename ... Args>
  void DoSomething(Args... args) { _m.DoSomething(args...); }
private:
  T _m;
};

然后我有了另一个标头,定义了要在模板专业化中使用的类:

#pragma once

#include <string>
#include <iostream>

class Bar {
public:
  Bar(std::string const & a,
      std::string const & b) :
        m_strA(a),
        m_strB(b) {}

  void DoSomething(int const one, int const two) {
    std::cout << "Str A: " << m_strA << ", Str B: "<<  m_strB << ", ints: " << one << ", " << two << std::endl;
  }

private:
  std::string m_strA;
  std::string m_strB;
};

我想使用SWIG及其模板化的成员函数包装 Foo 专长,以便可以从Lua脚本中使用它们。

我遇到的问题是SWIG并没有像我期望的那样为DoSomething模板化函数生成包装器。

在阅读了一些SWIG文档之后,我知道它无法使用%template 指令对参数包参数进行多次替换,因此我使用了%重命名

%module FooSwig
%include <std_string.i>

%{
#include "foo.hpp"
#include "bar.hpp"
%}

%include "foo.hpp"
%include "bar.hpp"

%rename(lua_foo) Foo<Bar, std::string const &, std::string const &>;
class Foo<Bar, std::string const &, std::string const &> {
public:
  Foo(std::string const &, std::string const &);

  template<typename ... Args>
  void DoSomething(Args... args);
private:
  Bar _m;
};

使用%template 指令不起作用(按预期方式),因为要替换的参数超过1个-我从swig中得到以下内容:

  

错误:模板“ DoSomething”未定义。

我想我需要再次使用%rename 解决这个问题,但我不知道如何解决。我尝试了以下方法:

%extend Foo<Bar, std::string const &, std::string const &>
{
  %rename(Do_Something) DoSomething<int const, int const>;
  void DoSomething(int const, int const);
}

这确实会产生一些东西,但是包装器包含一个未定义函数的符号:

Foo_Sl_Bar_Sc_std_string_SS_const_SA__Sc_std_string_SS_const_SA__Sg__DoSomething(arg1,arg2,arg3);

代替对成员函数模板的预期调用,类似

(arg1)->SWIGTEMPLATEDISAMBIGUATOR DoSomething<int const, int const>(arg2, arg3);

我没办法尝试了,也许你们中的一个可以帮忙?

有关我的环境的一些信息: 我正在使用g ++ 7.4.0,c ++ 17和SWIG 3.0。

2 个答案:

答案 0 :(得分:1)

我设法生成了包装器,并且包装器按预期工作。

这是旧的SWIG接口文件的摘要:

...
  template<typename ... Args>
  void DoSomething(Args... args);
...

我将其替换为以下内容:

...
  void DoSomething(int const, int const);
...

但是我仍然想知道是否有更好的方法来做到这一点,以便进一步了解任何信息(或阅读材料/源代码的指针)。

答案 1 :(得分:0)

我想到的最佳解决方法是编写多个模板类,每个类用于不同数量的模板参数,因为通常它们并不多。

相关问题