提问人:shouriha 提问时间:6/15/2023 最后编辑:shouriha 更新时间:6/15/2023 访问量:70
初始化 cppyy 中对象指针的 std::map
Initializing std::map of pointers of objects in cppyy
问:
我正在尝试从 cppyy 初始化从字符串到唯一指针的映射。我可以毫无问题地制作指针向量,但是当我制作地图时,我收到了 cppyy 的一些投诉。这是我的课程:
import cppyy
import cppyy.gbl as Cpp
cppyy.cppdef(r"""\
#include <cmath>
#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <memory>
class Zoo
{
// generic Zoo interface
public:
Zoo() = default;
virtual ~Zoo() = default;
virtual void printAnimals() = 0;
};
template<typename TAnimalType> class SpecificZoo:
public Zoo
{
public:
virtual std::vector<TAnimalType> getAnimals() = 0;
};
class Bird{
};
class Fish{
};
class Aquarium: public SpecificZoo<Fish>{
public:
void printAnimals() override {
std::cout << "fish";
}
std::vector<Fish> getAnimals() override {
return {};
}
};
class Aviary: public SpecificZoo<Bird>{
public:
void printAnimals() override {
std::cout << "Birds";
}
std::vector<Bird> getAnimals() override {
return {};
}
};
int main(){
std::vector<std::unique_ptr<Zoo>> zoos{};
auto aquarium = std::make_unique<Aquarium>();
zoos.push_back(std::move(aquarium));
auto aviary = std::make_unique<Aviary>();
zoos.push_back(std::move(aviary));
std::cout << zoos.size() << std::endl;
std::cout << "Done making zoo vector" << std::endl;
std::map<std::string, std::unique_ptr<Zoo>> zooMap{};
auto aquarium2 = std::make_unique<Aquarium>();
auto aviary2 = std::make_unique<Aviary>();
zooMap.emplace("aquarium", std::move(aquarium2));
zooMap.emplace("aviary", std::move(aviary2));
std::cout << zooMap.size() << std::endl;
std::cout << "Done making zoo map" << std::endl;
}
""")
要制作指针向量,我可以做:
zoos = Cpp.std.vector[Cpp.std.unique_ptr[Cpp.Zoo]]()
print("Created zoos")
aquarium = Cpp.Aquarium()
aviary = Cpp.Aviary()
zoos.push_back(Cpp.std.move(aquarium))
zoos.push_back(Cpp.std.move(aviary))
但是,为了制作地图,我尝试了:
zooDict = Cpp.std.map[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Zoo]]()
aquarium2 = Cpp.std.make_unique[Cpp.Aquarium]()
aviary2 = Cpp.std.make_unique[Cpp.Aviary]()
print(aquarium2)
zooDict.emplace('aquarium', Cpp.std.move(aquarium2))
zooDict.emplace('aviary', Cpp.std.move(aviary2))
print(f'Zoo dict created? {zooDict}')
for key, val in zooDict:
print(key, val)
崩溃并显示以下错误:
IncrementalExecutor::executeFunction: symbol '_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10unique_ptrI3ZooSt14default_deleteISB_EEEEE9constructISF_JS8_8AquariumEEEvPT_DpOT0_' unresolved while linking symbol '__cf_15'!
You are probably missing the definition of void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Aquarium>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, Aquarium&&)
Maybe you need to load the corresponding shared library?
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[5], line 6
3 aviary2 = Cpp.std.make_unique[Cpp.Aviary]()
5 print(aquarium2)
----> 6 zooDict.emplace('aquarium', Cpp.std.move(aquarium2))
7 zooDict.emplace('aviary', Cpp.std.move(aviary2))
9 print(f'Zoo dict created? {zooDict}')
ValueError: Template method resolution failed:
std::pair<std::_Rb_tree_iterator<std::pair<const std::string,std::unique_ptr<Zoo,std::default_delete<Zoo> > > >,bool> std::map<std::string,std::unique_ptr<Zoo,std::default_delete<Zoo> > >::emplace(std::string&& __args, Aquarium&& __args) =>
ValueError: nullptr result where temporary expected
我也试过不创建:unique_ptr
zooDict = Cpp.std.map[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Zoo]]()
aquarium2 = Cpp.Aquarium()
aviary2 = Cpp.Aviary()
zooDict.emplace('aquarium', Cpp.std.move(aquarium2))
zooDict.emplace('aviary', Cpp.std.move(aviary2))
print(f'Zoo dict created? {zooDict}')
for key, val in zooDict:
print(key, val)
崩溃并显示以下错误:
IncrementalExecutor::executeFunction: symbol '_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10unique_ptrI3ZooSt14default_deleteISB_EEEEE9constructISF_JS8_8AquariumEEEvPT_DpOT0_' unresolved while linking symbol '__cf_12'!
You are probably missing the definition of void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Aquarium>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, Aquarium&&)
Maybe you need to load the corresponding shared library?
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
Cell In[5], line 5
2 aquarium2 = Cpp.Aquarium()
3 aviary2 = Cpp.Aviary()
----> 5 zooDict.emplace('aquarium', Cpp.std.move(aquarium2))
6 zooDict.emplace('aviary', Cpp.std.move(aviary2))
8 print(f'Zoo dict created? {zooDict}')
ValueError: Template method resolution failed:
std::pair<std::_Rb_tree_iterator<std::pair<const std::string,std::unique_ptr<Zoo,std::default_delete<Zoo> > > >,bool> std::map<std::string,std::unique_ptr<Zoo,std::default_delete<Zoo> > >::emplace(std::string&& __args, Aquarium&& __args) =>
ValueError: nullptr result where temporary expected
最后,我尝试不移动对象,不制作指针,这不会崩溃,但它仍然会产生警告消息
zooDict = Cpp.std.map[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Zoo]]()
aquarium2 = Cpp.Aquarium()
aviary2 = Cpp.Aviary()
zooDict.emplace('aquarium', aquarium2)
zooDict.emplace('aviary', aviary2)
print(f'Zoo dict created? {zooDict}')
for key, val in zooDict:
print(key, val)
IncrementalExecutor::executeFunction: symbol '_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10unique_ptrI3ZooSt14default_deleteISB_EEEEE9constructISF_JS8_R8AquariumEEEvPT_DpOT0_' unresolved while linking symbol '__cf_12'!
You are probably missing the definition of void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, Aquarium&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&&, Aquarium&)
Maybe you need to load the corresponding shared library?
我应该做些什么来不收到此错误消息吗?我是否正确创建了这个对象?
编辑以回应@273k的回答。这样做几乎可以奏效,我在单元格第一次运行时收到警告,但如果我再次运行它,警告就会消失。(python 的字符串会自动转换为 Cpp.std.string,但即使我明确这样做,警告仍然存在。
zooDict = Cpp.std.map[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Zoo]]()
aquarium2 = Cpp.Aquarium()
aviary2 = Cpp.Aviary()
zooDict.emplace(Cpp.std.make_pair[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Zoo]]('aquarium', Cpp.std.move(aquarium2)))
zooDict.emplace(Cpp.std.make_pair[Cpp.std.string, Cpp.std.unique_ptr[Cpp.Zoo]]('aviary', Cpp.std.move(aviary2)))
print(f'Zoo dict created? {zooDict}')
for key, val in zooDict:
print(key, val)
val.printAnimals()
返回:
IncrementalExecutor::executeFunction: symbol '_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10unique_ptrI3ZooSt14default_deleteISB_EEEEE9constructISF_JRS2_IS8_SE_EEEEvPT_DpOT0_' unresolved while linking symbol '__cf_13'!
You are probably missing the definition of void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Zoo, std::default_delete<Zoo> > >&>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Zoo, std::default_delete<Zoo> > >&)
Maybe you need to load the corresponding shared library?
IncrementalExecutor::executeFunction: symbol '_ZN9__gnu_cxx13new_allocatorISt13_Rb_tree_nodeISt4pairIKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt10unique_ptrI3ZooSt14default_deleteISB_EEEEE9constructISF_JPS2_IS8_SE_EEEEvPT_DpOT0_' unresolved while linking symbol '__cf_14'!
You are probably missing the definition of void __gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > > > >::construct<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::unique_ptr<Zoo, std::default_delete<Zoo> > >*&&)
Maybe you need to load the corresponding shared library?
Zoo dict created? <cppyy.gbl.std.map<std::string,std::unique_ptr<Zoo,std::default_delete<Zoo> > > object at 0x55588a7f6fc0>
aquarium <cppyy.gbl.Zoo object at 0x55588a997be0 held by std::unique_ptr<Zoo,std::default_delete<Zoo> > at 0x55588b270bb0>
fish
aviary <cppyy.gbl.Zoo object at 0x55588a982cf0 held by std::unique_ptr<Zoo,std::default_delete<Zoo> > at 0x55588b364e00>
Birds
在第一次尝试时,但随后再次运行它返回:
Zoo dict created? <cppyy.gbl.std.map<std::string,std::unique_ptr<Zoo,std::default_delete<Zoo> > > object at 0x55588a7f6fc0>
aquarium <cppyy.gbl.Zoo object at 0x55588a997be0 held by std::unique_ptr<Zoo,std::default_delete<Zoo> > at 0x55588b270bb0>
fish
aviary <cppyy.gbl.Zoo object at 0x55588a982cf0 held by std::unique_ptr<Zoo,std::default_delete<Zoo> > at 0x55588b364e00>
Birds
答:
0赞
273K
6/15/2023
#1
std::map::emplace(Args&&... args)
期望 中 ,该类型为 。std::map::value_type
args
std::pair<const std::string, std::unique_ptr<Zoo>>
zooDict.emplace('aquarium', Cpp.std.move(aquarium2))
应该是 smth 喜欢(我不熟悉 cppyy)
zooDict.emplace(Cpp.std.make_pair('aquarium', Cpp.std.move(aquarium2)))
也许需要更改为'aquarium'
Cpp.std.string('aquarium')
评论