如何包装可变模板类的可变模板成员函数?

我有一个包含可变模板定义的头文件,该头文件还包含一些可变模板成员函数。为了简洁起见,以下代码片段已经显著简化和裁剪:

#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指令,因此我使用了%rename**代替:

%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**指令不起作用(预期),因为有多个参数要替换-我从swig中得到以下内容:

Error: Template 'DoSomething' undefined.

我想我需要再次使用**%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。

点赞
用户9118298
用户9118298

我已经成功生成了包装器,它的工作符合预期。

这是老的 SWIG 接口文件代码片段:

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

我用以下代码取代了它:

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

不过我仍然好奇是否有更好的方法来做到这一点,如果有更多的信息(或阅读材料/源代码的指针),欢迎分享。

2019-08-14 15:50:38
用户7398118
用户7398118

最好的解决方案是编写多个模板类,每个类针对不同数量的模板参数,因为通常模板参数并不多。

2021-05-10 17:27:06