今天使用STL列表。第一次使用一个,我对成员函数并不十分熟悉,我不确定我是否完全理解迭代器。不过,我已经完成了研究,似乎无法理解为什么STL列表中的插入函数要求我传递3个参数
note: candidate expects 3 arguments, 2 provided
Houses.insert(it,temp);
这是我的代码的一部分。仅供参考,此位始终显示多次,并且每次都会出现错误。
temp = new WolfDen;
it = Houses.begin();
Houses.insert(it,temp);
temp -> setDimensions();
Houses是我的STL“家园”列表。 WolfDen是一个派生类的家庭。 temp是homes指针,它是我的列表迭代器。
答案 0 :(得分:1)
基于评论Houses
可能被定义为
std::list<Home> Houses;
和WolfDen
继承自Home;
class WolfDen : public Home
由于您可能打算使用整个WolfDen
对象,因此需要存储指针:
std::list<Home *> Houses;
或现代C ++(自C ++ 11以来):
std::list<std::unique_ptr<Home>> Houses;
如果您使用裸指针变体std::list<Home *>
,请确保在完成它们后删除指向的对象。例如。在离开定义Houses
的范围之前就做
for (std::list<Home *>::const_iterator homeIt = Houses.begin(),
homeEnd = Houses.end();
homeIt != homeEnd; ++homeIt)
{
delete *homeIt;
}
如果您将定义保留为std::list<Home>
,则会编译以下insert语句:
Houses.insert(it,*temp);
但是这会将另一个Home
对象插入Houses
,这只是存储在该位置的Home
对象WolfDen
的{{1}}部分的副本由*temp
指出。 (新对象将为temp
)
随后的修改
Houses.front()
只会修改原始对象temp->setDimensions();
而不会修改*temp
。此外,对象Houses.front()
可能会泄漏,除非您添加
*temp
代码末尾。
然而,更好的是,根本不使用指针:
delete temp;
(注意,未使用类Home temp;
temp.setDimensions();
it = Houses.begin();
Houses.insert(it,temp);
,因为无论如何只会使用WolfDen
部分。)
Home
要理解这一点,请查看http://en.cppreference.com/w/cpp/container/list/insert:您打算调用的版本是note: candidate expects 3 arguments, 2 provided
的版本(1)
std::list::insert
其中T是Home。即。
iterator insert( iterator pos, const T & value ); (1)
对于参数iterator insert( iterator pos, const Home & value );
,您提供了pos
类型的参数,这很好。但是对于参数std::list<Home>::iterator
,您提供了类型为value
的参数(或可能Home *
转换为WolfDen *
),这是一个指针。指针不会隐式转换为值(或在这种情况下引用值)。因此,与版本(1)的匹配失败。
但是,指针会隐式转换为整数类型。由于还有其他版本的Home *
,编译器也会尝试这些版本。前两个提供的参数与http://en.cppreference.com/w/cpp/container/list/insert中的版本(3)匹配:
std::list::insert
void insert( iterator pos, size_type count, const T & value ); (3)
类型的指针会转换为Home *
。但是后来缺少第三个参数size_type
...有些编译器更精细,列出了可能的候选者以及有关失败匹配的更多信息。
如果不需要value
,您的代码可能已编译。由于指针通常会转换为相当大的值,因此您的应用程序会向value
添加相当多的条目。 (您可以通过将代码更改为Houses
来尝试此操作。但请准备好耗尽内存; - ))。