使用默认值从 partially-specified 模板 class 继承时出现 SWIG 错误,前向声明没有默认值

SWIG error when inheriting from partially-specified template class with defaults, with forward declaration without defaults

我在尝试为我想使用的库生成 SWIG 接口时遇到错误。该代码包含一个 class,它继承自包含默认值的模板化 class。但是,模板化的 class 也有一个不包含默认值的前向声明。我认为这令人困惑。

这是一个简单的例子:

frac.h (parent class):

#pragma once

// forward declaration
template <typename A, typename B>
class Frac;

// ... code using the forward declaraton

// definition
template <typename A=int, typename B=int>
class Frac
{
public:
    A a;
    B b;

    double divide()
    {
        return a / b;
    };
};

timestwo.h (child class):

#pragma once

#include "frac.h"

class TimesTwo : public Frac<double>
{
public:
    double getValue()
    {
        a = 10.5;
        b = 4;

        return divide() * 2;
    }
};

mylib.i 文件:

%module mylib
 %{
 #include "timestwo.h"
 %}

%include "frac.h"

/*
If no %template is used:

mylib.h:15: Warning 401: Nothing known about base class 'Frac< double >'. Ignored.
mylib.h:15: Warning 401: Maybe you forgot to instantiate 'Frac< double >' using %template.
*/

/*
If put here: %template(frac_d) Frac <double>;

mylib.i:15: Error: Not enough template parameters specified. 2 required.
*/

/*
If put here: %template(frac_d) Frac <double, int>;

timestwo.h:5: Warning 401: Nothing known about base class 'Frac< double >'. Ignored.
timestwo.h:5: Warning 401: Maybe you forgot to instantiate 'Frac< double >' using %template.
*/

%include "timestwo.h"

mylib.i 的评论所示,我似乎无法正确实例化模板,因为我需要使用一个模板参数,但由于前向声明没有指定默认值,它说它期待两个。

这只是一个警告。是要实例化Frac还是调用divide?否则,它有效:

>>> import mylib
>>> t = mylib.TimesTwo()
>>> t.getValue()
5.25

如果您希望能够调用 divide(),SWIG 似乎不理解模板默认值。它通过使用 Frac<double,int> 更新 timestwo.h 来工作,但如果您不想修改 header,您可以手动复制 .i 文件中的定义并进行更正:

%module mylib
%{
#include "timestwo.h"
%}

%include "frac.h"
%template(frac_d) Frac<double,int>; // Frac<double> doesn't work as of SWIG 3.0.12.

// Declare the interface the way SWIG likes it.
class TimesTwo : public Frac<double,int>
{
public:
    double getValue();
};

演示:

>>> import mylib
>>> t = mylib.TimesTwo()
>>> t.getValue()
5.25
>>> t.divide()
2.625