STL 列表插入要求 3 个参数

STL List Insert asks for 3 arguments

今天使用 STL 列表。第一次使用,我对成员函数不是很熟悉,我不确定我是否完全理解迭代器。 Non-the-less,我做了研究,似乎无法理解为什么 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 是我 "homes" 的 STL 列表。 WolfDen 是派生的 class 家园。 temp 是 homes 指针,它是我的列表迭代器。

假设

根据评论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 中,它只是存储在 WolfDen 对象 *tempHome 部分的副本temp 指向的位置。 (新对象将是Houses.front()

后续修改

temp->setDimensions();

只会修改原始对象 *temp 而不会 Houses.front()。此外,对象 *temp 可能会泄漏,除非您添加

delete temp;

在您的代码末尾。

不过,更好的是,根本不用指针:

Home temp;
temp.setDimensions();
it = Houses.begin();
Houses.insert(it,temp);

(请注意,未使用 class 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 是家。即

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()); 来尝试此操作。但请准备好 运行 内存不足 ;-))。