错误:没有匹配函数调用 '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&lt;std::unique_ptr&lt;Pet&gt; 并将Cat() 更改为std::make_unique&lt;Cat&gt;()unique_ptr 将安全地为您处理内存管理。 您好,我按照您所说的做了,当我尝试返回我的 newVector 时出现错误 - 错误:无法从 'std::vector<:unique_ptr> >' 到 'std::vector' 代码:std::vector<:unique_ptr>> newVector; newVector.push_back(std::make_unique ());返回新向量; 类型必须始终保持不变。如果你返回一个``std::vector<:unique_ptr>>, the variable receiving it needs to be a std::vector<:unique_ptr>>` 【参考方案1】:

OPs 代码中的错误:

std::vector<Pet*> newVector Cat(), Dog();

Cat() 创建Cat 的临时实例。类型为Cat(或Cat&amp;)。 std::vector&lt;Pet*&gt; 的元素类型是 Pet*,这是不兼容的。应用地址运算符 (&amp;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&lt;Pet*&gt; 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&lt;Pet&gt; 允许指针本身被删除后立即删除。

【讨论】:

以上是关于错误:没有匹配函数调用 'std::vector<Pet*>::vector(<brace-enclosed initializer list>)'的主要内容,如果未能解决你的问题,请参考以下文章

错误:没有匹配函数调用‘std::vector<std::__cxx11::basic_string<char> >::push_back(int&)’

错误:没有用于调用'variable'的匹配函数

创建函数变体向量时出现“调用没有匹配函数”错误

没有匹配函数调用‘std::vector::push_back(std::string&)’

当我尝试从 main 调用我的类模板函数时出现错误

如何处理 std::vector 的错误?