使用默认值从 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
我在尝试为我想使用的库生成 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