错误:没有匹配函数调用 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)'
Posted
技术标签:
【中文标题】错误:没有匹配函数调用 \'std::vector<Pet*>::vector(<brace-enclosed initializer list>)\'【英文标题】:error: no matching function for call to 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)'错误:没有匹配函数调用 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)' 【发布时间】:2019-11-19 03:49:09 【问题描述】:您好,我需要帮助解决 C++ 的此错误。 我正在尝试创建一个返回包含宠物对象的向量的函数。 我尝试使用 pushback,仍然无法编译。 我还有一堆其他类(猫、狗、鱼等)也继承了宠物基类。
这是我的功能的一个片段。
std::vector<Pet*> make_pets()
//why doesn't this work?
std::vector<Pet*> newVector Cat(), Dog();
return newVector;
//newVector.push_back(c);
【问题讨论】:
Cat()
是 Pet
,而不是 Pet*
。您的目标可能是new Cat()
,但最好将vector
更改为std::vector<std::unique_ptr<Pet>
并将Cat()
更改为std::make_unique<Cat>()
。 unique_ptr
将安全地为您处理内存管理。
您好,我按照您所说的做了,当我尝试返回我的 newVector 时出现错误 - 错误:无法从 'std::vector<:unique_ptr> >' 到 'std::vector, the variable receiving it needs to be a
std::vector<:unique_ptr>>`
【参考方案1】:
OPs 代码中的错误:
std::vector<Pet*> newVector Cat(), Dog();
Cat()
创建Cat
的临时实例。类型为Cat
(或Cat&
)。
std::vector<Pet*>
的元素类型是 Pet*
,这是不兼容的。应用地址运算符 (&Cat()
) 会使事情变得更糟。虽然现在类型会匹配(如果Cat
派生自Pet
,则可以将Cat*
分配给Pet*
),Cat()
会创建一个 临时 实例。它没有提供足够的生命周期,因为它会在表达式结束时自动销毁,这会在 std::vector
中留下一个悬空指针。
要解决这个问题,可以使用new
:
std::vector<Pet*> newVector new Cat(), new Dog();
大肠杆菌上的 MCVE:
#include <iostream>
#include <memory>
#include <vector>
struct Pet
virtual ~Pet() = default;
virtual const char* what() const = 0;
;
struct Cat: public Pet
virtual const char* what() const override return "cat";
;
struct Dog: public Pet
virtual const char* what() const override return "dog";
;
std::vector<Pet*> make_pets()
std::vector<std::unique_ptr<Pet>> vec new Cat(), new Dog() ;
return vec;
int main()
std::vector<std::unique_ptr<Pet>> pets = make_pets();
std::cout << "Pets:\n";
for (const Pet *pPet : pets) std::cout << pPet->what() << '\n';
for (const Pet *pPet : pets) delete pPet;
输出:
Pets:
cat
dog
Live Demo on coliru
使用new
创建实例会导致必须使用delete
显式销毁这些实例。只是清除 std::vector<Pet*>
pets
会导致实例未被删除并丢失——内存泄漏。
std::unique_ptr(由@user4581301 推荐)的用法有点棘手。因为std::unique_ptr
的实例是唯一拥有/持有指针的实例,所以它可能不会被复制或分配,而只是移动。经过一番摆弄,我得到了一个关于 coliru 的 mcve:
#include <iostream>
#include <memory>
#include <vector>
struct Pet
virtual ~Pet() = default;
virtual const char* what() const = 0;
;
struct Cat: public Pet
virtual const char* what() const override return "cat";
;
struct Dog: public Pet
virtual const char* what() const override return "dog";
;
std::vector<std::unique_ptr<Pet>> make_pets()
std::vector<std::unique_ptr<Pet>> vec;
vec.emplace_back(std::make_unique<Cat>());
vec.emplace_back(std::make_unique<Dog>());
return vec;
int main()
std::vector<std::unique_ptr<Pet>> pets = make_pets();
std::cout << "Pets:\n";
for (const std::unique_ptr<Pet> &pPet : pets) std::cout << pPet->what() << '\n';
输出:
Pets:
cat
dog
Live Demo on coliru
在这种情况下,Pet
实例的销毁不是问题。 std::unique_ptr<Pet>
允许指针本身被删除后立即删除。
【讨论】:
以上是关于错误:没有匹配函数调用 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)'的主要内容,如果未能解决你的问题,请参考以下文章
错误:没有匹配函数调用‘std::vector<std::__cxx11::basic_string<char> >::push_back(int&)’