简体   繁体   English

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

[英]How can I wrap a variadic template member function of a variadic template class in SWIG?

I have a header file containing the definition of a variadic template, which also contains a few variadic templated member functions.我有一个包含可变参数模板定义的头文件,其中还包含一些可变参数模板化成员函数。 Code snippets below have been significantly simplified and cut down for brevity:为简洁起见,以下代码片段已显着简化和缩减:

#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;
};

I then have another header defining a class to be used in a template specialization:然后我有另一个头文件定义了一个在模板特化中使用的类:

#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;
};

I would like to wrap the Foo specialization using SWIG, as well as its templated member function, so I can use them from a Lua script.我想使用 SWIG 及其模板化成员函数包装Foo专业化,以便我可以从 Lua 脚本中使用它们。

The problem I am encountering is that SWIG is not generating a wrapper for the DoSomething templated function as I expect.我遇到的问题是 SWIG 没有像我期望的那样为 DoSomething 模板化函数生成包装器。

After reading some of the SWIG documentation, I am aware that it is unable to use the %template directive with more than 1 substitution for the parameter pack arguments, so I have used %rename instead:在阅读了一些 SWIG 文档后,我知道它无法使用%template指令对参数包参数进行 1 次以上的替换,因此我改用了%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;
};

Using the %template directive doesn't work (as expected), as there are more than 1 parameters to substitute - I get the following from swig:使用%template指令不起作用(如预期的那样),因为有 1 个以上的参数需要替换 - 我从 swig 得到以下信息:

Error: Template 'DoSomething' undefined.错误:模板“DoSomething”未定义。

I imagine I need to get around this using %rename again, but I can't figure out how.我想我需要再次使用%rename来解决这个问题,但我不知道如何解决。 I've tried the following:我尝试了以下方法:

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

And that does generate something, but the wrapper contains a symbol for a function that is undefined:这确实生成了一些东西,但包装器包含一个未定义函数的符号:

Foo_Sl_Bar_Sc_std_string_SS_const_SA__Sc_std_string_SS_const_SA__Sg__DoSomething(arg1,arg2,arg3);

instead of the expected call to a member function template, something along the lines of而不是对成员函数模板的预期调用,类似于

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

I'm running out of things to try, and maybe one of you can help?我没有什么可以尝试的了,也许你们中的一个可以帮忙?

Some info about my environment: I'm using g++ 7.4.0, c++ 17 and SWIG 3.0.关于我的环境的一些信息:我使用的是 g++ 7.4.0、c++ 17 和 SWIG 3.0。

I managed to get the wrapper generated and it works as expected.我设法生成了包装器并且它按预期工作。

This is a snippet of the old SWIG interface file:这是旧的 SWIG 接口文件的片段:

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

I replaced it with the following:我用以下内容替换了它:

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

However I am still curious to find out whether there is a better way to do it so any further info (or pointers to reading materials/source code) would be appreciated.但是,我仍然很想知道是否有更好的方法来做到这一点,因此我们将不胜感激任何进一步的信息(或指向阅读材料/源代码的指针)。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM