【问题标题】:"In file included from error" with vector带有矢量的“在错误中包含的文件中”
【发布时间】:2018-11-30 03:33:03
【问题描述】:

我正在尝试创建一个聚合类 Pile,它将卡片向量作为其数据。

在过去的 3 个小时里,我一直在试图弄清楚这个错误是怎么回事,我很困惑。这是错误:

In file included from /usr/include/c++/5/vector:62:0,
                 from Pile.h:16,
                 from Pile.cpp:15:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, _Args&& ...) [with _T1 = Card; _Args = {}]’:
/usr/include/c++/5/bits/stl_uninitialized.h:519:18:   required from ‘static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Card*; _Size = long unsigned int; bool _TrivialValueType = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:575:20:   required from ‘_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = Card*; _Size = long unsigned int]’
/usr/include/c++/5/bits/stl_uninitialized.h:637:44:   required from ‘_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = Card*; _Size = long unsigned int; _Tp = Card]’
/usr/include/c++/5/bits/stl_vector.h:1311:36:   required from ‘void std::vector<_Tp, _Alloc>::_M_default_initialize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = Card; _Alloc = std::allocator<Card>; std::vector<_Tp, _Alloc>::size_type = long unsigned int]’
/usr/include/c++/5/bits/stl_vector.h:279:30:   required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const allocator_type&) [with _Tp = Card; _Alloc = std::allocator<Card>; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<Card>]’
<span class="error_line" onclick="ide.gotoLine('Pile.cpp',27)">Pile.cpp:27:23</span>:   required from here
/usr/include/c++/5/bits/stl_construct.h:75:7: error: no matching function for call to ‘Card::Card()’
     { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
       ^
In file included from Pile.h:17:0,
                 from Pile.cpp:15:
card.h:30:5: note: candidate: Card::Card(const Card&)
     Card(const Card& old);     //copy constructor
     ^
card.h:30:5: note:   candidate expects 1 argument, 0 provided
card.h:29:5: note: candidate: Card::Card(int, char)
     Card(int r, char s); //parameterized constructor
     ^
card.h:29:5: note:   candidate expects 2 arguments, 0 provided

Call Stack
#   Function    File:Line
Local Variables
Variable    Value
Display Expressions
Expression  Value   
Breakpoints and Watchpoints
    #   Description 

我觉得我已经很接近了,我有很多其他错误我能够解决,但我无法通过这个“包含在文件中”的错误,因为我什至无法弄清楚它的含义。我已经单独测试了我的卡片类,它按预期运行。

这是我的 Pile.h 代码:

#ifndef PILE_H
#define PILE_H
#include <vector>
#include "card.h"

using namespace std;

class Pile 
{
protected:
    vector<Card> p;

public:

    Pile();
    Pile(vector<Card> p);

    Card dealCard();
    int getCount();
    void shuffle();
    void clear();
    Pile operator + (const Card& c) const;
    Pile operator + (Pile& b);
    friend ostream& operator << (ostream& out, const Pile& p);

};

这是我的 Pile.cpp 代码:

#include "Pile.h"
#include <iomanip>
#include <algorithm>  //shuffle
#include <time.h>
#include <sstream>
#include <stdexcept>
#include <cstdlib>

using namespace std;

Pile::Pile()
{
    p = vector<Card>(0);
}

Pile::Pile(vector<Card> p)
{
    this->p = p;
}

//draws card from the top of the pile and removes it from the vector
Card Pile:: dealCard()
{
    if(p.size() > 0)
    {
        Card tempCard = p.front();
        p.erase(p.begin());

        return tempCard;
    }
    else
        throw std::length_error("Pile is empty");


}

int Pile:: getCount()
{
    return p.size();
}

void Pile:: shuffle()
{
    srand(unsigned(time(NULL)));
    random_shuffle(p.begin(), p.end());
}

void Pile:: clear()
{
    p.clear();
}

Pile Pile:: operator + (const Card& c) const
{
    Pile tempPile(p);       //make a copy of the pile to be returned
    tempPile.p.push_back(c);  //push the new card onto the end of the pile
    return tempPile;        //return the new pile
}

Pile Pile:: operator + (Pile& b)
{
    Pile tempPile(p);

    while(b.p.size() > 0)
    {
        tempPile.p.push_back(b.p.front());
        b.p.erase(b.p.begin());
    }
    return tempPile;
}

ostream& operator << (ostream& out, const Pile& p)
{
    int count = 0;
    int index = 0;

    while(p.p.size() > 0)
    {
        out << p.p[index] << setw(2);
        count++;
        index++;

        if(count == 10)
        {
            out << endl;
            count = 0;
        }
    }
}

我最好的猜测是我可能在某处缺少#include。在过去的几个小时里,我尝试用谷歌搜索这个问题,我唯一能想到的就是移动“使用命名空间 std”,但我已经尝试过了,但我仍然收到错误。

编辑:

这是我的 Card.cpp

#include <cstdlib>
#include "card.h"
#include <sstream>
#include <stdexcept>
using namespace std;

Card::Card(int r, char s)
{
    if(r <= 13 && r > 0)
        this->r = r;
    else
        throw std::invalid_argument("Rank must be valid (1-13)");

    if(s == 'd' || s == 'D')        //diamonds
        this->s = 'D';
    else if(s == 'h' || s == 'H')   //hearts
        this->s = 'H';
    else if(s == 's' || s == 'S')   //spades
        this->s = 'S';
    else if(s == 'c' || s == 'C')   //clubs
        this->s == 'C';
    else
        throw std::invalid_argument("Suit must be valid (H, S, C, D");
}

Card::Card(const Card& old)
{
    r = old.r;
    s = old.s;
}

void Card::setCard(int r, char s)
{
    if(r <= 13 && r > 0)
        this->r = r;
    else
        throw std::invalid_argument("Rank must be valid (1-13)");

    if(s == 'd' || s == 'D')        //diamonds
        this->s = 'D';
    else if(s == 'h' || s == 'H')   //hearts
        this->s = 'H';
    else if(s == 's' || s == 'S')   //spades
        this->s = 'S';
    else if(s == 'c' || s == 'C')   //clubs
        this->s == 'C';
    else
        throw std::invalid_argument("Suit must be valid (H, S, C, D");
}

int Card::getRank()
{
    return r;
}

 bool Card:: operator == (const Card c) const
 {
     if(r == c.r)
         return true;
     else
         return false;
 }

 bool Card:: operator >(const Card c) const
 {
     if(r > c.r)
         return true;
     else
         return false;
 }

 ostream& operator << (ostream& out, const Card c)
 {
     if(c.r == 1)
         out << "A" << c.s;
     else if(c.r > 1 && c.r <= 10)
         out << c.r << c.s;
     else if(c.r == 11)
         out << "J" << c.s;
     else if(c.r == 12)
         out << "Q" << c.s;
     else      //must be king
         out << "K" << c.s;
 }

和card.h:

#ifndef CARD_H
#define CARD_H

#include <string>
#include <iostream>
using namespace std;

class Card
{
private:
    int r;      
    char s;

public:

    Card(int r, char s); //parameterized constructor
    Card(const Card& old);     //copy constructor

    void setCard(int r, char s);
    int getRank();
    bool operator ==(const Card c) const;
    bool operator >(const Card c) const;
    friend ostream& operator << (ostream& out, const Card c);

};

【问题讨论】:

  • 没有匹配函数调用‘Card::Card()’看起来 Card 需要一个默认构造函数。
  • srand 通常只应在每个程序广告中调用一次,这看起来通常属于这种情况。将其从Pile:: shuffle() 中删除,并将其放在main 函数顶部附近的某个位置。
  • Card 不需要用户定义的复制构造函数或赋值运算符。此外,您可能不需要默认构造函数,但如果 vector 需要它怎么办?啊哈。
  • 真正的错误信息以error: no matching function for call to ‘Card::Card()’开头,它之前的内容解释了在此问题发生之前我们在编译过程中所处的位置

标签: c++ vector


【解决方案1】:

问题是这一行:

p = vector<Card>(0);

以这种方式初始化向量需要一个默认构造函数。请参阅std::vector constructor (3)。您可以简单地删除该行,因为它确实没有必要。无论如何,std::vector 一开始都是空的,所以不需要做多余的工作。

您会看到,如果您删除该行,您会注意到您的代码无需默认构造函数即可编译。但是,如果您添加更多代码,则需要注意不要以需要默认构造函数的方式使用 std::vector。因此,仅仅提供一个默认构造函数可能并没有什么坏处。


话虽如此,您的代码产生了一些您需要解决的警告。例如,在您重载的&lt;&lt; 运算符中,您未能返回值。从应该返回值的函数中不返回任何内容会导致未定义的行为

另一个问题是您无需为PileCard 编写用户定义的复制构造函数,因为这两个类的所有成员都包含正确的复制语义(int、@987654329 @,用于Card 类,std::vector&lt;Card&gt; 用于Pile 类)。无需介绍编译器免费提供给你的代码,没有bug,效率高。

【讨论】:

    【解决方案2】:

    缺少 Card 类的默认构造函数。当类中存在用户定义的构造函数(带参数或不带参数)时,C++ 不会生成默认构造函数。 在您的代码中,需要在 Pile.cpp:27 中使用默认构造函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-11
      • 1970-01-01
      • 2013-11-23
      相关资源
      最近更新 更多