在模板化函数中重新定义(忽略)的 SWIG 标识符

SWIG Identifier redefined (ignored) in templated function

本文关键字:定义 标识符 SWIG 忽略 新定义 函数      更新时间:2023-10-16

我已经阅读了许多其他关于使用模板的帖子,但有一个独特的问题,我可以将其简化为最小的情况。 例如

%include <stl.i>
%include <std_array.i>
%module example
%inline %{
template <typename T>  T ExampleFunc(){
return (T)0;
}
template <typename T, unsigned int N>  std::array<T, N> ExampleFunc(){
std::array<T, N> empty;
return empty;
}
%}
%template(Int2) std::array<int, 2>;
%template(ExampleFuncInt) ExampleFunc<int>;
%template(ExampleFuncDouble) ExampleFunc<double>;
%template(ExampleFuncInt2) ExampleFunc<int, 2>;

使用swig -python -c++ example.i生成时,上述内容会产生以下警告和错误

example.i(13) : Warning 302: Identifier 'ExampleFunc' redefined (ignored),
example.i(9) : Warning 302: previous definition of 'ExampleFunc'.
example.i(20) : Error: Template 'ExampleFunc' undefined.

我知道这是因为两个模板函数具有没有模板的签名,但在我的实际示例中,我需要模板声明同一函数的标量和数组版本。重命名 cpp 库中的函数不是一个选项,使用%rename指令不起作用,因为这会重命名函数的两个版本并产生相同的警告。

%include <stl.i>
%include <std_array.i>
%module example
%inline %{
template <typename T>  T ExampleFunc(){
return (T)0;
}
template <>  std::array<int, 2> ExampleFunc(){
std::array<int, 2> empty;
return empty;
}
%}
%template(Int2) std::array<int, 2>;
%template(ExampleFuncInt2) ExampleFunc<std::array<int, 2>>;
%template(ExampleFuncInt) ExampleFunc<int>;
%template(ExampleFuncDouble) ExampleFunc<double>;

这有效,但有警告。

模板专用化不需要由 SWIG 处理,因此我将其从%inline声明中删除,并添加了#include <array>以便对其进行编译。

ExampleFuncInt2的模板声明是错误的。 还初始化了empty

此 SWIG 没有警告,编译 @/W3 时没有警告:

%module example
%{
#include <array>
%}
%inline %{
template <typename T>  T ExampleFunc(){
return (T)0;
}
%}
%{
template <>  std::array<int, 2> ExampleFunc(){
std::array<int, 2> empty{};
return empty;
}
%}
%include <std_array.i>
%template(Int2) std::array<int, 2>;
%template(ExampleFuncInt) ExampleFunc<int>;
%template(ExampleFuncDouble) ExampleFunc<double>;
%template(ExampleFuncInt2) ExampleFunc<std::array<int, 2>>;

演示:

>>> import example
>>> example.ExampleFuncInt()
0
>>> example.ExampleFuncDouble()
0.0
>>> example.ExampleFuncInt2()
(0, 0)