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é!
S'il vous plaît créer un [mcve] –