这里有一个中景:
食品储藏室
%module(directors="1") my_collection
%include "stdint.i"
%include "std_string.i"
%include "std_shared_ptr.i"
%include "std_vector.i"
%{
#include "my_collection.cpp"
%}
%nodefaultctor;
%shared_ptr(Food);
%include "my_collection.cpp"
餐具室.cpp
#pragma once
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <sstream>
#ifdef SWIG
%define TO_STRING()
%extend {
%feature("python:slot", "tp_repr", functype="reprfunc") to_string;
}
std::string to_string()
%enddef
%define SUBSCRIPT(return_type, subscript_type)
%feature("python:slot", "mp_subscript", functype="binaryfunc") __getitem__;
%extend {
return_type __getitem__(subscript_type key) {
return (*($self))[key];
};
};
return_type operator[](subscript_type key)
%enddef
#else
#define TO_STRING() \
std::string to_string()
#define SUBSCRIPT(return_type, subscript_type) \
return_type operator[](subscript_type key)
#endif
class Food {
public:
std::string name;
Food(std::string name) {
this->name = name;
};
TO_STRING() {
std::ostringstream stream;
stream << "<Food " << this->name << ">";
return stream.str();
};
};
class Pantry {
private:
// _foods is not grammatically correct
std::map<std::string, std::shared_ptr<Food>> _food_map;
std::vector<std::shared_ptr<Food>> _food_vec;
public:
Pantry() {
};
std::shared_ptr<Food> add(std::string name) {
auto food = std::shared_ptr<Food>(new Food(name));
this->_food_map[food->name] = food;
this->_food_vec.push_back(food); // p.s., how do I prevent making a copy?
return food;
};
SUBSCRIPT(std::shared_ptr<Food>, std::string) {
return this->_food_map.at(key);
};
TO_STRING() {
return "<Pantry>";
};
std::vector<std::shared_ptr<Food>>::const_iterator begin() {
return this->_food_vec.begin();
};
std::vector<std::shared_ptr<Food>>::const_iterator end() {
return this->_food_vec.end();
};
size_t size() {
return this->_food_vec.size();
};
};
我还编写了一个简短的Python脚本:
import pantry
pant = mc.Pantry()
print(pant.add('Bacon'))
print(pant.add('Cheese'))
print('subscript[Bacon]: {}'.format(pant['Bacon']))
for food in pant:
print('iter: ... {}'.format(food))
然后,根据-builtin
标志是否传递给SWIG,我得到错误:
-builtin
:TypeError: in method 'Pantry___getitem__', argument 2 of type 'std::string'
--这是有意义的,因为我选择了按字符串索引-builtin
:TypeError: 'my_collection.Pantry' object is not iterable
--我认为这是由于SWIG没有隐式地创建我没有声明的方法造成的,这在本例中似乎是正确的。你知道吗如何迭代集合内容而不显式调用方法?我意识到我可以将_food_vec
公开并迭代,但是我的实际代码更复杂,我不想这样做。同样,我可以实现一些其他的.iterate()
方法,但是我已经完成了begin()
和end()
的工作。你知道吗
编辑:我可以实现什么样的目标语言不可知方法,类似于我为TO_STRING()
和SUBSCRIPT
创建的宏,以及添加到接口文件的正确模板是什么(类似于%template(FoodIterator) std::vector<Food>::iterator;
)?你知道吗
您有two options来实现iterable接口:
__iter__()
,它返回一个具有next()
的对象实例。你知道吗__getitem__()
。你知道吗我想这应该可以解释这两个错误,同时也可以提供一个如何修复的线索。你知道吗
相关问题 更多 >
编程相关推荐