0

Je suis très nouveau en C++ et je tente de créer une calculatrice simple qui suit des conventions mathématiques (BODMAS ou PEMDAS). J'ai fait une calculatrice de fonction, mais j'ai ensuite décidé d'aller plus loin et d'accepter les variables, à quel point j'ai continué à recevoir l'erreur C2280.ERREUR C++: C2280- erreur de compilation qui fait référence à la fonction supprimée?

L'erreur est:

token_stream::token_stream(void): attempting to reference a deleted function

Je simplement ne comprennent ce que cela signifie et ne savent pas quoi faire pour y remédier.

Voici la classe token_stream:

class token_stream { //creates a stream of tokens 
public: 
    Token get(); //call to get token function 
    void putback(Token t); //call to token putback function 
    void ignore(char a); // call to ignore bad tokens function 

private: 
    bool full{ false }; //is there a token in the buffer? 
    Token buffer; //this is where putback token is stored 
}; 

Voici l'intégralité du code de calcul:

#include "../../std_lib_facilities.h" 

//--------------------------------------------------------------------------------------------------- 

class Token //user defined type with two member functions 
{ 
public: 
    char kind; 
    double value; 
    string name; 

    Token(char ch) : kind{ ch } {} //initialize kind with ch 
    Token(char ch, double val) : kind{ ch }, value{ val } {} //initialize kind and value 
    Token(char ch, string name) : kind{ ch }, name{ name } {} //initialize kind and name 
}; 
class token_stream { //creates a stream of tokens 
public: 
    Token get(); //call to get token function 
    void putback(Token t); //call to token putback function 
    void ignore(char a); // call to ignore bad tokens function 

    private: 
    bool full{ false }; //is there a token in the buffer? 
    Token buffer; //this is where putback token is stored 
}; 
class Variable { 
public: 
    string name; 
    double val; 
}; 

//--------------------------------------------------------------------------------------------------- 

const char number = '8'; //t.kind==number means that t is a number token 
const char quit = 'q'; //t.kind==quit means that t is a quit token 
const char print = ';'; //t.kind==print means that t is a print token 
const char name = 'a'; 
const char let = 'L'; 
const string declr_key = "let"; 
vector<Variable> var_table; 
token_stream ts; 
//--------------------------------------------------------------------------------------------------- 

void token_stream::putback(Token t) { 
    if (full) error("putback() is full"); //tests precondition to see if buffer is full 
    buffer = t; 
    full = true; 
} 
void token_stream::ignore(char c) { 
    if (full && c == buffer.kind) { 
     full = false; 
     return; 
    } 
    char ch{ 0 }; 
    while (cin >> ch) { 
     if (c == ch) 
      return; 
    } 
} 
Token token_stream::get() { //creates a token from inputs 
    if (full) { //checks if we have a token ready 
     full = false; 
     return buffer; 
    } 
    char ch; 
    cin >> ch; 
    switch (ch) { 
    case print: 
    case quit: 
    case '(': 
    case ')': 
    case '+': 
    case '-': 
    case '*': 
    case '/': 
    case '%': 
     return Token{ ch }; break; //let each character represent itself 
    case '.':      // floatng point literal can start with a dot 
    case '0': case '1': case '2': case '3': case '4': 
    case '5': case '6': case '7': case '8': case '9': 
    { 
     cin.putback(ch);   //putback the digit into input stream 
     double val; 
     cin >> val;     //read a floating point number 
     Token t{ number,val }; 
     return t; 
     break; 
    } 
    default: 
     if (isalpha(ch)) { 
      string s; 
      s += ch; 
      while (cin.get(ch) && (isalpha(ch) || isdigit(ch))) s += ch; 
      cin.putback(ch); 
      if (s == declr_key) return Token{ let }; 
      return Token{ name, s }; 

     } 
     error("Error in Input: Token Invalid"); break; 
    } 
} 

double get_value(string s) {   //gets the value for a given variable 
    for (int i = 0; i < var_table.size(); i++) 
     if (s == var_table[i].name) return var_table[i].val; 
    error("Undefined variable: ", s); 
} 
void set_value(string s,double d) {  // sets the value for a pre-defined variable 
    for (int i = 0; i < var_table.size(); i++) 
     if (s == var_table[i].name) { 
      var_table[i].val = d; 
      return; 
     } 
    error("Undefined variable: ", s); 
} 

//--------------------------------------------------------------------------------------------------- 

double primary(); //declaration so that term can call primary() 
double term() { //does multiplication, division, and modulo 
    double left = primary(); 
    Token t = ts.get(); 
    while (true) 
    { 
     switch (t.kind) { 
     case '*': 
     { 
      left *= primary(); 
      t = ts.get(); 
      break; 
     } 

     case '/': { 
      double d = primary(); 
      if (d == 0) error("Divide by 0!"); //non-zero denom check 
      else { 
       left /= d; 
       t = ts.get(); 
      } 
      break; 
     } 
     case '%': { 
      double d = primary(); 
      if (d == 0)error("Divide by 0!"); //non-zero denom check 
      else { 
       left = fmod(left, d); 
       t = ts.get(); 
      } 
      break; 
     } 

     default: ts.putback(t); //put back in token strem if none of the other options 
      return left; break; 
     } 
    } 
} 
double expression() { //handles +, - 
    double left = term(); 
    Token t = ts.get(); 
    while (true) { 
     switch (t.kind) { 
     case '+': 
     { 
      left += term(); 
      t = ts.get(); 
      break; } 
     case '-': { 
      left -= term(); 
      t = ts.get(); 
      break; } 
     default: ts.putback(t); //put back into token stream if none of the options above 
      return left; 
      break; 
     } 
    } 

} 
double primary() { 
    Token t = ts.get(); 
    switch (t.kind) { 
    case '(': 
    { 
     double d = expression(); 
     t = ts.get(); 
     if (t.kind != ')') error("Expected a ')'"); 
     return d; 
     break; 
    } 
    case number: 
     return t.value; 
     break; 
    case '-': //handles negative numbers 
     return - primary(); 
     break; 
    case '+': //handles positive numbers which are preceded by '+' 
     return primary(); 
     break; 
    default: error("primary expected: no value after operator given. check input"); 
    } 
} 

void check_var(string name) { 
    for (int i = 0; i < var_table.size(); i++) 
     if (name == var_table[i].name) 
      error("Variable name already exists"); 
} 
double define_name(string name, double num) { 
    check_var(name); 
    var_table.push_back(Variable{ name, num }); 
    return num; 
} 
double declaration() { 
    // assume we have seen a 'let' 
    // handles: name=expression 
    // declare a variable called 'name' with value 'val' 
    Token t = ts.get(); 
    if (t.kind != name) error("Expected a variable name"); //throws an error if no variable name given 
    string var_name = t.name; 

    t = ts.get(); 
    if (t.kind != '=')error("No '=' sign present in declaration of ", var_name); 

    double d = expression(); 
    define_name(var_name, d); 
    return d; 
} 
double statement() { 
    Token t = ts.get(); 
    switch (t.kind) { 
    case let: 
     return declaration(); 
    default: 
     ts.putback(t); 
     return expression(); 
    } 
} 

void clean_up_mess() { 
    ts.ignore(print); 
} 
void calculate() { //expression evaluation loop 
    while (cin) 
    { 
     try { 
      Token t = ts.get(); 
      if (t.kind == print) t = ts.get(); //first discard all 'prints' 
      if (t.kind == quit) { 
       return; 
      } 
      ts.putback(t); 
      cout << "Answer: " << statement() << "\n"; 
     } 
     catch (exception&e) { 
      cout << "Error: " << e.what() << "\n"; 
      clean_up_mess(); 
     } 
    } 
} 

//--------------------------------------------------------------------------------------------------- 

int main() 
{ 
    try { 
     cout << "Enter an expression to solve: \n"; //user prompt 
     calculate(); 
     keep_window_open(); 
    } 
    catch(...) { 
     cout << "Error of Unknown origin.\n"; 
    } 

} 

Toute aide est vraiment apprécié!

+0

S'il vous plaît créer un [mcve] –

Répondre

0

Comme Token n'a pas de constructeur par défaut (un constructeur qui peut être appelé sans aucun paramètre), et token_stream contient Token, le compilateur ne peut pas générer de constructeur par défaut pour token_stream.

Deux solutions possibles:

  1. Ajouter un constructeur par défaut à Token
  2. Ajouter un constructeur par défaut à token_stream, initialisant buffer à une valeur
+0

Merci beaucoup! Cela l'a réparé! –