【发布时间】:2019-03-26 18:06:02
【问题描述】:
抱歉,标题太长了,这是我想要实现的目标:我有一个带有 bool 模板参数的小型 C++ 类,当它为真时,它使用 std::enable_if 禁用它的 setter 方法。这是一个简化的例子:
template< bool IS_CONST >
class Handle
{
public:
Handle(void) : m_value(0) { }
Handle(int value) : m_value(value) { }
template < bool T = IS_CONST, typename COMPILED = typename std::enable_if< T == false >::type >
void set(int value)
{
m_value = value;
}
int get(void) const
{
return m_value;
}
private:
int m_value;
};
此代码按预期编译工作:Handle< true > 没有 set 方法,Handle< false > 有。
现在我正在尝试使用 SWIG 将其绑定到 Python。我正在使用以下文件来生成绑定:
%module core
%include "Handle.h"
%template(NonConstHandle) Handle< false >;
%template(ConstHandle) Handle< false >;
%{
#include "Test.h"
%}
SWIG 毫无怨言地生成了模块,它编译得很好,但是 set 方法永远不会被绑定,即使在专门的 NonConstHandle 中也是如此。例如以下 Python 测试以 AttributeError: 'NonConstHandle' object has no attribute 'set' 失败:
import core
handle = core.NonConstHandle()
assert(handle.get() == 0)
handle.set(1)
assert(handle.get() == 1)
const_handle = core.ConstHandle()
assert(const_handle .get() == 0)
try:
const_handle .set(1)
print("this should not print")
except:
pass
print("all good")
当我搜索这个主题时,我发现了很多与 enable_if 和 SWIG 相关的东西,这让我认为它是受支持的,但我不知道为什么没有生成 set,尽管没有错误/警告由 SWIG 发出...
任何帮助表示赞赏! 问候
【问题讨论】:
-
您需要更改
#include和%include的顺序。即便如此,我怀疑SWIG是否能够解决这个问题。有许多c++11、c++14... 功能仅在关键字不会产生编译错误的意义上得到支持。 -
enable_if 一直可以追溯到 C++98,尽管它直到 11 才在 boost 之外标准化。
-
@JensMunk 有什么理由说明订单很重要吗?据我所见,除了 #include 出现在生成的 cxx 文件中的行之外,更改它不会改变任何事情,并且在这两种情况下似乎都没有太大区别。
-
@Flexo 你是什么意思?
-
在你的情况下,它可能没有什么不同。我遇到了一些情况,其中 SWIG
.i文件中使用的符号被解析为未定义,除非我包含相关的 C 头文件。您需要注意的另一件事是 SWIG 不会递归标头