C++ 做C++;在映射中插入对时需要附加代码吗?

C++ 做C++;在映射中插入对时需要附加代码吗?,c++,stl,stdmap,std-pair,C++,Stl,Stdmap,Std Pair,你好,伟大的StackOverflow社区! 我正在制作一些C++,当在 STD::MAP< > < /P>中插入元素时,我遇到了一个问题。 这里有两个映射,将一个ID(如unsigned int)存储为键,另一个对象存储为值: std::map\u fifos; 标准:地图厨房; 两个映射在类中都是private,我在该类的public方法中插入如下内容: fifonewfifo(\u internalCount); 厨房新厨房(_args,newFIFO); _厨房.插页(标准:制作配对

你好,伟大的StackOverflow社区! 我正在制作一些C++,当在<代码> STD::MAP< <代码> > < /P>中插入元素时,我遇到了一个问题。 这里有两个映射,将一个ID(如
unsigned int
)存储为键,另一个对象存储为值:

std::map\u fifos;
标准:地图厨房;
两个映射在类中都是
private
,我在该类的
public
方法中插入如下内容:

fifonewfifo(\u internalCount);
厨房新厨房(_args,newFIFO);
_厨房.插页(标准:制作配对(_internalCount,newKitchen));
_fifos.insert(std::make_pair(_internalCount,newFIFO));

麻烦就从这里开始。
我的编辑器(VSCode)和编译器(g++)似乎都接受
\u fifos.insert()
,但不接受
\u kitchens.insert()

VSCode告诉我们:

no instance of overloaded function "std::map<_Key, _Tp, _Compare, _Alloc>::insert [with _Key=unsigned int, _Tp=Kitchen, _Compare=std::less<unsigned int>, _Alloc=std::allocator<std::pair<const unsigned int, Kitchen>>]" matches the argument list..."
如果您需要什么或需要更多详细信息,请告诉我:)


编辑2:
我在这里添加了一些来自g++的附加错误/注释提交(显示在上面的初始问题中)

/usr/include/c++/9/bits/stl_-pair.h:436:9:note:candidate:'template std::pair::pair(std::tuple&,std::tuple&,std:_Index_-tuple,std:_-Index_-tuple)'
436 |对(元组&,元组&,
/usr/include/c++/9/bits/stl_pair.h:436:9:注意:模板参数推导/替换失败:
/usr/include/c++/9/bits/stl_pair.h:529:14:注意:不匹配的类型“std::tuple”和“unsigned int”
529返回对类型(std::forward(uuuux),std::forward(uuy));
一如既往,提前感谢您的时间和建议


编辑3:
我现在开始把脑子里的一切联系起来,谢谢大家。 这里的事情很棘手,但我肯定从你的建议中学到了很多。我会再次仔细阅读@Restore monica的答案,并在我身边做进一步的研究,我有办法解决这个问题,让它变得更好。
很抱歉,我没有想到我的第一个问题会如此棘手,我想让它更清楚。
我的下一个问题将更清楚,我将从一开始就尽量减少可复制代码,我将仔细研究StackOverflow@ted lyngmo!的良好实践

感谢大家的支持和时间,保重自己!

首先,你应该安置,而不是插入-这避免了复制:

_kitchens.emplace(_internalCount, std::move(newKitchen));
_fifos.emplace(_internalCount, std::move(newFIFO));
其次,
Kitchen
可能既不可复制也不可移动,这就是你的问题所在。确保它可以复制或至少可以移动。如果可以,你必须展示一个最小的示例。我可以写一个,但它会起作用,而一个不起作用的变体将是微不足道的,没有任何帮助。因此,请先展示你的作品:)

第三:我不知道FIFO对象的设计,但在构造函数中将其临时实例传递给
Kitchen
,可能只是一个bug。当完成所有这些工作的函数退出时,
Kitchen
将有一个悬空的引用。因此,你真正想要的是:

auto fifo_it = _fifos.emplace(std::piecewise_construct, {_internalCount}, {_internalCount}).first;
if (fifo_it.second)
  // if the new fifo was actually inserted
  _kitchens.emplace(std::piecewise_construct, {_internalCount}, {_args, fifo_it.first->second});
通过这种方式,厨房将参考fifo,至少在长寿方面有很好的机会

我非常怀疑将
\u internalCount
传递给地图和地图中包含的对象。这种信息的重复通常是一种糟糕的设计味道

你应该告诉我们你想要实现什么,一个更好的设计可能会出现

class Kitchen {
public:
    Kitchen() = delete;
    Kitchen(Args args, FIFO newFifo);
    ~Kitchen();

既然定义了析构函数,C++就足够聪明,可以实现默认拷贝,并且移动构造函数和赋值几乎肯定是错误的,因此它不会为您生成默认值。因此,不可能复制

厨房

Kitchen newKitchen(_args, newFIFO);
_kitchens.insert(std::make_pair(_internalCount, newKitchen));

insert获取一对,并尝试将其复制到映射中。如果没有复制构造函数,它就无法做到这一点。有两种解决办法。显而易见的一点是使厨房可复制,但这可能很棘手。更好的解决方案是不复制kitchen,而是让地图创建一个新的
kitchen
,如中所示。

我们可能需要了解更多关于
kitchen
的信息,以查看它在复制这样一个方面是否有限制…创建一个。其余的错误消息在哪里?你已经删除了错误的部分,告诉我们问题是什么(你好)MooingDuck,从C++的地下有很多错误。,有两个错误很有趣,但我不太清楚:
c++
@Charlie如果你做了一个测试,我们会更容易帮助你。删除所有不需要重现问题的内容,并包括重现问题所需的内容。
Args
类型似乎很重要,但你还没有包括它的定义。你因此,我错过了很多标题。我现在让它更接近mcve。请填空。非常感谢这些详细信息!我将使用
emplace()
。我将密切关注您的第三点。这是我考虑悬挂引用和(隐式?)的第一步临时定义,我想我错过了很多关于对象构造或生命周期的事情。在堆中传递对象并分配它们可以解决这个“引用”问题或者,只有您的实例化方式才能正确地实例化对象,而不是将其保留为临时对象?哇,哇,哇,什么?如果在编译器为您完成所有工作时,您无法跟踪对象的生命周期,那么您认为如果您将手动内存管理添加到混合中会有什么好处?不要。不要手动堆除非必要,否则分配。
map
已经为您完成了所有这些。这就是它的工作。这就是您使用它的原因。当您可以按值存储东西时,忘记堆。您将使事情变得更加困难。而且您将手动执行
新建
Kitchen newKitchen(_args, newFIFO);
_kitchens.insert(std::make_pair(_internalCount, newKitchen));