将 SWIG 与 C++ 模板函数结合使用
Using SWIG with C++ template functions
我在 C++ 中有几个用于映射的模板函数,我想在 ruby 中使用它们。
template <class Collection>
const typename Collection::value_type::second_type& FindWithDefault(
const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return value;
}
return it->second;
}
在 C++ 中它是这样工作的
int main(int argc, char const *argv[])
{
typedef std::map<std::string, std::string> Map;
Map m;
std::string d= FindWithDefault(m, "foo", "");
std::cout << d << "\n";
//
m["foo"] = "bar";
d= FindWithDefault(m, "foo", "");
std::cout << d << "\n";
// bar
}
在ruby中使用map和set很简单,看我之前回答过的问题的答案(看看)。
关于这个问题我的界面文件有这个
%include <std_map.i>
namespace std {
%template(IntMap) map<int,int>;
}
template <typename Collection>
const typename Collection::value_type::second_type& FindWithDefault(
const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) ;
%template(d) FindWithDefault<std::map<int,int> >;
我的c++头文件有上面提到的完整功能。现在,当我尝试在 Irb 中检查时,地图工作正常,但我在使用模板函数时遇到错误
2.2.1 :001 > a = Example::IntMap.new
=> std::map<int,int,std::less< int >,std::allocator< std::pair< int const,int > > > {}
2.2.1 :002 > a[1]=2
=> 2
2.2.1 :003 > a[5]=3
=> 3
2.2.1 :004 > a[4]=11
=> 11
2.2.1 :005 > a
=> std::map<int,int,std::less< int >,std::allocator< std::pair< int const,int > > > {1=>2,4=>11,5=>3}
2.2.1 :006 > b=Example::d(a,2,2)
ArgumentError: Wrong arguments for overloaded method 'd'.
Possible C/C++ prototypes are:
std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::second_type const & d(int a, int b)
std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::second_type const & d(std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > > const &collection, std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::first_type const &key, std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::second_type const &value)
from (irb):6:in `d'
from (irb):6
from /usr/share/rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
我怎样才能完成这项工作?
SWIG 似乎无法确定 Collection::value_type::first_type
和 Collection::value_type::second_type
的类型。我不太清楚为什么。
在这种情况下恰好可行的一种可能的解决方案/解决方法是将 Collection::value_type::first_type
替换为 Collection::key_type
并将 Collection::value_type::second_type
替换为 Collection::mapped_type
。在 SWIG 接口文件中执行此操作就足够了,即,保持 C++ 代码不变,但将其放入接口文件中:
%include <std_map.i>
namespace std {
%template(IntMap) map<int,int>;
}
template <typename Collection>
const typename Collection::mapped_type& FindWithDefault(
const Collection& collection,
const typename Collection::key_type& key,
const typename Collection::mapped_type& value) ;
%template(d) FindWithDefault<std::map<int,int> >;
我在 C++ 中有几个用于映射的模板函数,我想在 ruby 中使用它们。
template <class Collection>
const typename Collection::value_type::second_type& FindWithDefault(
const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) {
typename Collection::const_iterator it = collection.find(key);
if (it == collection.end()) {
return value;
}
return it->second;
}
在 C++ 中它是这样工作的
int main(int argc, char const *argv[])
{
typedef std::map<std::string, std::string> Map;
Map m;
std::string d= FindWithDefault(m, "foo", "");
std::cout << d << "\n";
//
m["foo"] = "bar";
d= FindWithDefault(m, "foo", "");
std::cout << d << "\n";
// bar
}
在ruby中使用map和set很简单,看我之前回答过的问题的答案(看看
关于这个问题我的界面文件有这个
%include <std_map.i>
namespace std {
%template(IntMap) map<int,int>;
}
template <typename Collection>
const typename Collection::value_type::second_type& FindWithDefault(
const Collection& collection,
const typename Collection::value_type::first_type& key,
const typename Collection::value_type::second_type& value) ;
%template(d) FindWithDefault<std::map<int,int> >;
我的c++头文件有上面提到的完整功能。现在,当我尝试在 Irb 中检查时,地图工作正常,但我在使用模板函数时遇到错误
2.2.1 :001 > a = Example::IntMap.new
=> std::map<int,int,std::less< int >,std::allocator< std::pair< int const,int > > > {}
2.2.1 :002 > a[1]=2
=> 2
2.2.1 :003 > a[5]=3
=> 3
2.2.1 :004 > a[4]=11
=> 11
2.2.1 :005 > a
=> std::map<int,int,std::less< int >,std::allocator< std::pair< int const,int > > > {1=>2,4=>11,5=>3}
2.2.1 :006 > b=Example::d(a,2,2)
ArgumentError: Wrong arguments for overloaded method 'd'.
Possible C/C++ prototypes are:
std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::second_type const & d(int a, int b)
std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::second_type const & d(std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > > const &collection, std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::first_type const &key, std::map< int,int,std::less< int >,std::allocator< std::pair< int const,int > > >::value_type::second_type const &value)
from (irb):6:in `d'
from (irb):6
from /usr/share/rvm/rubies/ruby-2.2.1/bin/irb:11:in `<main>'
我怎样才能完成这项工作?
SWIG 似乎无法确定 Collection::value_type::first_type
和 Collection::value_type::second_type
的类型。我不太清楚为什么。
在这种情况下恰好可行的一种可能的解决方案/解决方法是将 Collection::value_type::first_type
替换为 Collection::key_type
并将 Collection::value_type::second_type
替换为 Collection::mapped_type
。在 SWIG 接口文件中执行此操作就足够了,即,保持 C++ 代码不变,但将其放入接口文件中:
%include <std_map.i>
namespace std {
%template(IntMap) map<int,int>;
}
template <typename Collection>
const typename Collection::mapped_type& FindWithDefault(
const Collection& collection,
const typename Collection::key_type& key,
const typename Collection::mapped_type& value) ;
%template(d) FindWithDefault<std::map<int,int> >;