STL List Insert要求3个参数

时间:2016-04-05 04:59:45

标签: c++ stl arguments singly-linked-list

今天使用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指针,它是我的列表迭代器。

1 个答案:

答案 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来尝试此操作。但请准备好耗尽内存; - ))。