通过 emplace() 将对象指针插入到地图的地图中不起作用
Insert an object pointer into a map of maps through emplace() does not work
我试图通过 emplace()
将指针对象插入到 map
,但它不起作用。
我在下面创建了一个简单的问题表示。我正在尝试插入 newFooList
指针对象类型 Foo*
。
我似乎找不到在 std::map<int, FooMap*> m_fooMapList
中为 FooMap*
创建类型的方法。应该用地图第二个字段上的 new
来完成吗?
#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>
class Foo
{
private:
int m_foobar;
public:
Foo(int value)
{
m_foobar = value;
}
void setfoobar(int value);
int getfoobar();
};
class FooMap
{
private:
std::map<int, Foo*> m_newFoo;
public:
FooMap() = default;
};
class FooMapList
{
private:
std::map<int, FooMap*> m_fooMapList;
public:
FooMapList() = default;
void insertFoo(Foo* newFooObj);
};
int Foo::getfoobar(void)
{
return(m_foobar);
}
void FooMapList::insertFoo(Foo* newFooObj)
{
if(m_fooMapList.empty())
{
std::cout << "m_fooMapList is empty" << std::endl ;
}
//m_fooMapList.emplace( newFooObj->getfoobar(), newFooObj );
// Need to find a way to insert newFooObj to m_fooMapList
m_fooMapList.second = new FooMap;
}
int main() {
FooMapList newFooList;
for (auto i=1; i<=5; i++)
{
Foo *newFoo = new Foo(i);
newFoo->getfoobar();
newFooList.insertFoo(newFoo);
}
return 0;
}
在 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28) 上
$ g++ -std=c++11 -Wall map_of_map.cpp
map_of_map.cpp: In member function ‘void FooMapList::insertFoo(Foo*)’:
map_of_map.cpp:51:18: error: ‘class std::map<int, FooMap*>’ has no member named ‘second’
m_fooMapList.second = new FooMap;
除非你有充分的理由这样做,否则请避免像这样 Java 混淆事物,并尽可能利用 STL。为此,您可以使用类型别名
using FooMap = std::map<int, Foo*>; // Maybe use a smart pointer instead here?
using FooMapList = std::map<int, FooMap>; // Maybe List is not an appropriate name for a map
现在,您有一个刚刚创建的 Foo
元素并想将其插入地图列表中,为此您需要一种方法 select 在列表中的哪个地图中您想要插入它。我假设您将插入列表中的第一张地图:
auto FooMap::emplace(int key, Foo* value)
{
return m_newFoo.emplace(key, value);
}
void FooMapList::insertFoo(Foo* newFooObj)
{
// If the map for `getfoobar` does not exist yet, operator[] will create it
auto& mapPtr = m_fooMapList[newFooObj->getfoobar()];
if (nullptr == mapPtr)
mapPtr = new FooMap();
mapPtr->emplace(
newFooObj->getfoobar(),
newFooObj
);
}
请注意,我没有处理内存清理。我建议您在适用时尝试使用智能指针(std::unique_ptr
和 std::shared_ptr
)
m_fooMapList
定义为
std::map<int, FooMap*> m_fooMapList;
所以要插入其中,你需要一个 int
和一个指向 FooMap
的指针:
m_fooMapList.emplace(newFooObj->getfoobar(), new FooMap);
话虽如此,您应该使用 C++ 值语义并减少对原始指针的依赖:
std::map<int, FooMap> m_fooMapList; // no pointers
m_fooMapList.emplace(newFooObj->getfoobar(), {}); // construct objects in-place
也就是说,FooMap
的实例可以直接驻留在地图本身中。
这样您可以获得更好的性能并避免内存泄漏。
如果您真的想使用指针,也值得研究一下智能指针(例如 unique_ptr
)。
我不确定您是否需要一个地图结构,其中的值是指向另一个地图的指针。 FooMapList
class 可以很简单
std::map<int, FooMap> m_fooMapList;
另一方面,整个玩行指针只会让你感到脖子痛。
如果使用
std::map<int, FooMap*> m_fooMapList;
和 std::map<int, Foo*>
是必需的,我会选择智能指针。
以下是将行指针替换为 std::unique_ptr
的示例代码,并展示了如何将 Foo
的 map 插入到 map 就地。 See live here
#include <iostream>
#include <utility>
#include <map>
#include <memory>
class Foo
{
private:
int m_foobar;
public:
Foo(int value): m_foobar(value) {}
void setfoobar(int value) noexcept { m_foobar = value; }
int getfoobar() const noexcept { return m_foobar; }
};
class FooMap
{
private:
std::map<int, std::unique_ptr<Foo>> m_newFoo;
// ^^^^^^^^^^^^^^^^^^^^
public:
FooMap() = default;
#if 0 // optional
// copy disabled
FooMap(const FooMap&) = delete;
FooMap& operator=(const FooMap&) = delete;
// move enabled
FooMap(FooMap&&) = default;
FooMap& operator=(FooMap&&) = default;
#endif
// provide a helper function to insert new Foo to the map of Foo s
void insertFoo(std::unique_ptr<Foo> newFooObj)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
std::cout << "inserting to FooMap..." << std::endl;
m_newFoo.emplace(newFooObj->getfoobar(), std::move(newFooObj)); // construct in place
}
};
class FooMapList
{
private:
std::map<int, std::unique_ptr<FooMap>> m_fooMapList;
// ^^^^^^^^^^^^^^^^^^^^^^^
public:
FooMapList() = default;
void insertFooMap(std::unique_ptr<Foo> newFooObj)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
if (m_fooMapList.empty())
{
std::cout << "m_fooMapList is empty" << std::endl;
}
// create FooMap and insert Foo to it.
FooMap fooMap;
const auto key = newFooObj->getfoobar();
fooMap.insertFoo(std::move(newFooObj));
// finally insert the FooMap to m_fooMapList
std::cout << "inserting to fooMapList..." << std::endl;
m_fooMapList.emplace(key, std::make_unique<FooMap>(std::move(fooMap))); // construct in place
}
};
int main()
{
FooMapList newFooList;
for (auto i = 1; i <= 5; i++)
{
auto newFoo = std::make_unique<Foo>(i);
std::cout << newFoo->getfoobar() << std::endl;
newFooList.insertFooMap(std::move(newFoo));
}
return 0;
}
输出:
1
m_fooMapList is empty
inserting to FooMap...
inserting to fooMapList...
2
inserting to FooMap...
inserting to fooMapList...
3
inserting to FooMap...
inserting to fooMapList...
4
inserting to FooMap...
inserting to fooMapList...
5
inserting to FooMap...
inserting to fooMapList...
你可以扔掉你的无用地图类,停止使用指针,
#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>
class Foo
{
private:
int m_foobar;
public:
Foo(int value) : m_foobar(value) { }
void setfoobar(int value) { m_foobar = value; }
int getfoobar() const { return m_foobar; }
// or more simply
// int foobar;
};
using FooMap = std::map<int, Foo>;
using FooMapMap = std::map<int, FooMap>;
int main() {
FooMapMap foos;
for (auto i=1; i<=5; i++)
{
foos[i][i] = Foo(i);
}
return 0;
}
请注意,现阶段内部地图完全没有意义,因为它们只有一个条目
我考虑了每个答案的有效点以删除指针并删除无用的双层地图表示。但是现实世界的抽象是一个非常复杂的问题,它涉及到成千上万的动态对象,这些对象需要动态地创建和销毁。使用指针似乎是一种有效的方法,但 似乎好得多。
我尝试重新使用他的尝试,但使用对象指针和下面的方法似乎有效。使用以下插入函数
在 FooMap
class 中函数将是
void FooMap::insertFoo(Foo* newFooObj)
{
m_newFoo.emplace(newFooObj->getfoobar(), newFooObj);
}
const std::map<int, Foo*> FooMap::getList()
{
return m_newFoo;
}
在FooMapList
中会是
void FooMapList::insertFooList(Foo* newFooObj)
{
std::map <int, FooMap*>::iterator iter;
FooMap *localFooMap = NULL;
iter = m_fooMapList.find( newFooObj->getfoobar() );
if( iter == m_fooMapList.end() )
{
localFooMap = new FooMap;
localFooMap->insertFoo(newFooObj);
m_fooMapList.emplace(newFooObj->getfoobar(), localFooMap );
}
else
{
localFooMap = iter->second;
localFooMap->insertFoo(newFooObj);
m_fooMapList.emplace(newFooObj->getfoobar(), localFooMap );
}
}
const std::map<int, FooMap*> FooMapList::getList()
{
return m_fooMapList;
}
对于这种方法,我也很感激反馈。我将添加对析构函数的调用以清理创建的对象
我试图通过 emplace()
将指针对象插入到 map
,但它不起作用。
我在下面创建了一个简单的问题表示。我正在尝试插入 newFooList
指针对象类型 Foo*
。
我似乎找不到在 std::map<int, FooMap*> m_fooMapList
中为 FooMap*
创建类型的方法。应该用地图第二个字段上的 new
来完成吗?
#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>
class Foo
{
private:
int m_foobar;
public:
Foo(int value)
{
m_foobar = value;
}
void setfoobar(int value);
int getfoobar();
};
class FooMap
{
private:
std::map<int, Foo*> m_newFoo;
public:
FooMap() = default;
};
class FooMapList
{
private:
std::map<int, FooMap*> m_fooMapList;
public:
FooMapList() = default;
void insertFoo(Foo* newFooObj);
};
int Foo::getfoobar(void)
{
return(m_foobar);
}
void FooMapList::insertFoo(Foo* newFooObj)
{
if(m_fooMapList.empty())
{
std::cout << "m_fooMapList is empty" << std::endl ;
}
//m_fooMapList.emplace( newFooObj->getfoobar(), newFooObj );
// Need to find a way to insert newFooObj to m_fooMapList
m_fooMapList.second = new FooMap;
}
int main() {
FooMapList newFooList;
for (auto i=1; i<=5; i++)
{
Foo *newFoo = new Foo(i);
newFoo->getfoobar();
newFooList.insertFoo(newFoo);
}
return 0;
}
在 g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28) 上
$ g++ -std=c++11 -Wall map_of_map.cpp
map_of_map.cpp: In member function ‘void FooMapList::insertFoo(Foo*)’:
map_of_map.cpp:51:18: error: ‘class std::map<int, FooMap*>’ has no member named ‘second’
m_fooMapList.second = new FooMap;
除非你有充分的理由这样做,否则请避免像这样 Java 混淆事物,并尽可能利用 STL。为此,您可以使用类型别名
using FooMap = std::map<int, Foo*>; // Maybe use a smart pointer instead here?
using FooMapList = std::map<int, FooMap>; // Maybe List is not an appropriate name for a map
现在,您有一个刚刚创建的 Foo
元素并想将其插入地图列表中,为此您需要一种方法 select 在列表中的哪个地图中您想要插入它。我假设您将插入列表中的第一张地图:
auto FooMap::emplace(int key, Foo* value)
{
return m_newFoo.emplace(key, value);
}
void FooMapList::insertFoo(Foo* newFooObj)
{
// If the map for `getfoobar` does not exist yet, operator[] will create it
auto& mapPtr = m_fooMapList[newFooObj->getfoobar()];
if (nullptr == mapPtr)
mapPtr = new FooMap();
mapPtr->emplace(
newFooObj->getfoobar(),
newFooObj
);
}
请注意,我没有处理内存清理。我建议您在适用时尝试使用智能指针(std::unique_ptr
和 std::shared_ptr
)
m_fooMapList
定义为
std::map<int, FooMap*> m_fooMapList;
所以要插入其中,你需要一个 int
和一个指向 FooMap
的指针:
m_fooMapList.emplace(newFooObj->getfoobar(), new FooMap);
话虽如此,您应该使用 C++ 值语义并减少对原始指针的依赖:
std::map<int, FooMap> m_fooMapList; // no pointers
m_fooMapList.emplace(newFooObj->getfoobar(), {}); // construct objects in-place
也就是说,FooMap
的实例可以直接驻留在地图本身中。
这样您可以获得更好的性能并避免内存泄漏。
如果您真的想使用指针,也值得研究一下智能指针(例如 unique_ptr
)。
我不确定您是否需要一个地图结构,其中的值是指向另一个地图的指针。 FooMapList
class 可以很简单
std::map<int, FooMap> m_fooMapList;
另一方面,整个玩行指针只会让你感到脖子痛。
如果使用
std::map<int, FooMap*> m_fooMapList;
和 std::map<int, Foo*>
是必需的,我会选择智能指针。
以下是将行指针替换为 std::unique_ptr
的示例代码,并展示了如何将 Foo
的 map 插入到 map 就地。 See live here
#include <iostream>
#include <utility>
#include <map>
#include <memory>
class Foo
{
private:
int m_foobar;
public:
Foo(int value): m_foobar(value) {}
void setfoobar(int value) noexcept { m_foobar = value; }
int getfoobar() const noexcept { return m_foobar; }
};
class FooMap
{
private:
std::map<int, std::unique_ptr<Foo>> m_newFoo;
// ^^^^^^^^^^^^^^^^^^^^
public:
FooMap() = default;
#if 0 // optional
// copy disabled
FooMap(const FooMap&) = delete;
FooMap& operator=(const FooMap&) = delete;
// move enabled
FooMap(FooMap&&) = default;
FooMap& operator=(FooMap&&) = default;
#endif
// provide a helper function to insert new Foo to the map of Foo s
void insertFoo(std::unique_ptr<Foo> newFooObj)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
std::cout << "inserting to FooMap..." << std::endl;
m_newFoo.emplace(newFooObj->getfoobar(), std::move(newFooObj)); // construct in place
}
};
class FooMapList
{
private:
std::map<int, std::unique_ptr<FooMap>> m_fooMapList;
// ^^^^^^^^^^^^^^^^^^^^^^^
public:
FooMapList() = default;
void insertFooMap(std::unique_ptr<Foo> newFooObj)
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
{
if (m_fooMapList.empty())
{
std::cout << "m_fooMapList is empty" << std::endl;
}
// create FooMap and insert Foo to it.
FooMap fooMap;
const auto key = newFooObj->getfoobar();
fooMap.insertFoo(std::move(newFooObj));
// finally insert the FooMap to m_fooMapList
std::cout << "inserting to fooMapList..." << std::endl;
m_fooMapList.emplace(key, std::make_unique<FooMap>(std::move(fooMap))); // construct in place
}
};
int main()
{
FooMapList newFooList;
for (auto i = 1; i <= 5; i++)
{
auto newFoo = std::make_unique<Foo>(i);
std::cout << newFoo->getfoobar() << std::endl;
newFooList.insertFooMap(std::move(newFoo));
}
return 0;
}
输出:
1
m_fooMapList is empty
inserting to FooMap...
inserting to fooMapList...
2
inserting to FooMap...
inserting to fooMapList...
3
inserting to FooMap...
inserting to fooMapList...
4
inserting to FooMap...
inserting to fooMapList...
5
inserting to FooMap...
inserting to fooMapList...
你可以扔掉你的无用地图类,停止使用指针,
#include <iostream>
#include <utility>
#include <stdint.h>
#include <cstdlib>
#include <map>
class Foo
{
private:
int m_foobar;
public:
Foo(int value) : m_foobar(value) { }
void setfoobar(int value) { m_foobar = value; }
int getfoobar() const { return m_foobar; }
// or more simply
// int foobar;
};
using FooMap = std::map<int, Foo>;
using FooMapMap = std::map<int, FooMap>;
int main() {
FooMapMap foos;
for (auto i=1; i<=5; i++)
{
foos[i][i] = Foo(i);
}
return 0;
}
请注意,现阶段内部地图完全没有意义,因为它们只有一个条目
我考虑了每个答案的有效点以删除指针并删除无用的双层地图表示。但是现实世界的抽象是一个非常复杂的问题,它涉及到成千上万的动态对象,这些对象需要动态地创建和销毁。使用指针似乎是一种有效的方法,但
我尝试重新使用他的尝试,但使用对象指针和下面的方法似乎有效。使用以下插入函数
在 FooMap
class 中函数将是
void FooMap::insertFoo(Foo* newFooObj)
{
m_newFoo.emplace(newFooObj->getfoobar(), newFooObj);
}
const std::map<int, Foo*> FooMap::getList()
{
return m_newFoo;
}
在FooMapList
中会是
void FooMapList::insertFooList(Foo* newFooObj)
{
std::map <int, FooMap*>::iterator iter;
FooMap *localFooMap = NULL;
iter = m_fooMapList.find( newFooObj->getfoobar() );
if( iter == m_fooMapList.end() )
{
localFooMap = new FooMap;
localFooMap->insertFoo(newFooObj);
m_fooMapList.emplace(newFooObj->getfoobar(), localFooMap );
}
else
{
localFooMap = iter->second;
localFooMap->insertFoo(newFooObj);
m_fooMapList.emplace(newFooObj->getfoobar(), localFooMap );
}
}
const std::map<int, FooMap*> FooMapList::getList()
{
return m_fooMapList;
}
对于这种方法,我也很感激反馈。我将添加对析构函数的调用以清理创建的对象