STL 列表插入需要 3 个参数

问题描述 投票:0回答:2

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

c++ stl arguments singly-linked-list
2个回答
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>
,则以下插入语句将编译:

Houses.insert(it,*temp);

但这会将另一个

Home
对象插入到
Houses
中,该对象仅是存储在
Home
指向的位置的
WolfDen
对象
*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
部分。)

了解错误消息

note:   candidate expects 3 arguments, 2 provided

要了解这一点,请查看http://en.cppreference.com/w/cpp/container/list/insert:您要调用的版本是

std::list::insert

的版本(1)
iterator insert( iterator pos, const T & value ); (1)

其中 T 是 Home。即

iterator insert( iterator pos, const Home & value );

对于参数

pos
,您提供类型为
std::list<Home>::iterator
的参数,这很好。但是对于参数
value
,您提供了
Home *
类型的参数(或者可能是
WolfDen *
,它转换为
Home *
),它是一个指针。指针不会隐式转换为值(或在本例中为对值的引用)。因此与版本 (1) 的匹配失败。

但是,指针会隐式转换为整数类型。由于还有其他版本的

std::list::insert
,编译器也会尝试这些版本。提供的前两个参数与 http://en.cppreference.com/w/cpp/container/list/insert:

中的版本 (3) 匹配
void insert( iterator pos, size_type count, const T & value ); (3)

Home *
类型的指针转换为
size_type
。但是第三个参数
value
丢失了......一些编译器更详细并列出了可能的候选者以及有关失败匹配的更多信息。

如果不需要

value
,则您的代码可能已编译。由于指针通常会转换为相当大的值,因此您的应用程序会向
Houses
添加相当多的条目。 (您可以通过将代码更改为
Houses.insert(it,temp, WolfDen());
来尝试此操作。但要做好内存不足的准备;-))。


0
投票

我在自己的工作中注意到一次与此类似的错误。查看错误消息如何指向头文件 stl_vector.h,特别是第 1433 行,我查看了它,发现您可以尝试这样的操作:

std::vector <home>::iterator it;
Houses.insert(it, temp.begin(), temp.end());

可能的情况是,在将迭代器插入代码的过程中,std::list 类推断出上面的代码就是您想要的那种东西。我还发现,如果我在第一个参数中使用常规数字变量而不是迭代器,则其他两个参数可以只是数字,编译器会接受它(但这不适用于 std::strings,因为它们是一种指针数组而不是合法变量)。

© www.soinside.com 2019 - 2024. All rights reserved.