2010-05-05 2 views
0

Почему я получаю недопустимое объявление функции при компиляции кода в DevC++ в Windows, но когда я компилирую его в CodeBlocks на Linux, он отлично работает.Недопустимое объявление функции. DevC++

#include <iostream> 
#include <vector> 


using namespace std; 

//structure to hold item information 
struct item{ 
    string name; 
    double price; 
}; 

//define sandwich, chips, and drink 
struct item sandwich{"Sandwich", 3.00}; **** error is here ***** 
struct item chips{"Chips", 1.50};   **** error is here ***** 
struct item drink{"Large Drink", 2.00}; **** error is here ***** 

vector<item> cart;   //vector to hold the items 
double total = 0.0;   //total 
const double tax = 0.0825; //tax 

//gets item choice from user 
char getChoice(){ 

    cout << "Select an item:" << endl; 
    cout << "S: Sandwich. $3.00" << endl; 
    cout << "C: Chips. $1.50" << endl; 
    cout << "D: Drink. $2.00" << endl; 
    cout << "X: Cancel. Start over" << endl; 
    cout << "T: Total" << endl; 

    char choice; 
    cin >> choice; 
    return choice; 
} 

//displays current items in cart and total 
void displayCart(){ 
    cout << "\nCart:" << endl; 
    for(unsigned int i=0; i<cart.size(); i++){ 
     cout << cart.at(i).name << ". $" << cart.at(i).price << endl; 
    } 
    cout << "Total: $" << total << endl << endl; 
} 

//adds item to the cart 
void addItem(struct item bought){ 
    cart.push_back(bought); 
    total += bought.price; 
    displayCart(); 
} 

//displays the receipt, items, prices, subtotal, taxes, and total 
void displayReceipt(){ 

    cout << "\nReceipt:" << endl; 
    cout << "Items: " << cart.size() << endl; 
    for(unsigned int i=0; i<cart.size(); i++){ 
     cout << (i+1) << ". " << cart.at(i).name << ". $" << cart.at(i).price << endl; 
    } 
    cout << "----------------------------" << endl; 
    cout << "Subtotal: $" << total << endl; 

    double taxes = total*tax; 
    cout << "Tax: $" << taxes << endl; 

    cout << "Total: $" << (total + taxes) << endl; 


} 




int main(){ 

    //sentinel to stop the loop 
    bool stop = false; 
    char choice; 
    while (stop == false){ 

     choice = getChoice(); 

     //add sandwich 
     if(choice == 's' || choice == 'S'){ 
      addItem(sandwich); 
     } 
     //add chips 
     else if(choice == 'c' || choice == 'C'){ 
      addItem(chips); 
     } 
     //add drink 
     else if(choice == 'd' || choice == 'D'){ 
      addItem(drink); 
     } 
     //remove everything from cart 
     else if(choice == 'x' || choice == 'X'){ 
      cart.clear(); 
      total = 0.0; 
      cout << "\n***** Transcation Canceled *****\n" << endl; 
     } 
     //calcualte total 
     else if(choice == 't' || choice == 'T'){ 
      displayReceipt(); 
      stop = true; 
     } 
     //or wront item picked 
     else{ 
      cout << choice << " is not a valid choice. Try again\n" << endl; 
     } 

    }//end while loop 


    return 0; 
    //end of program 
} 

ответ

1

Вы упускаете оператор присваивания там:

struct item sandwich = {"Sandwich", 3.00}; 

Обратите внимание, что это синтаксис C, хотя. Вы, наверное, хотите сказать

item sandwich("Sandwich", 3.00); 

и добавить в item конструктор, который принимает string и double.

1

struct item sandwich{"Sandwich", 3.00}; является использование compound literal, что является законным в C (стандарт C99), но еще не законным в C++. Но так как большинство компиляторов C++ компилируют и C и C++-код, некоторые решают разрешить такие структуры на C++. Однако большинство из них не имеют специальных аргументов командной строки.

Таким образом, для того, чтобы это было законным и переносимым, вам нужно написать конструктор для вашего элемента struct. Это очень просто, хотя

struct item { 
    item(string const & name_, double price_) : name(name_), price(price_) {} 
    string name; 
    double price; 
}; 

И теперь вы можете создавать новые элементы с

item sandwich("Sandwich", 3.00); 

P.S. Обратите внимание, что я бы использовал именованные инициализаторы в сложных литералах, когда у вас есть поля с разным значением в единой структуре, просто понять, что тогда тогда.

struct item sandwich = {.name = "Sandwich", .price = 3.0}; 

Это тоже не сработает на C++, но, по крайней мере, оно выглядит лучше.

P.P.S. Оказывается, я не уделял достаточного внимания C++ 0x, и там он называется initializer lists. Похоже, вы не можете назвать его, но это позор. Итак, вместо использования стандарта C99 в коде на C++ ваш компилятор Linux использовал молчаливые экспериментальные стандарты C++ 0x. Тем не менее, если вам нужен кроссплатформенный код, все равно лучше держаться подальше от этих причудливых функций и вместо этого использовать простые старые конструкторы.

+0

LOL _ «Это не сработает ... но, по крайней мере, это выглядит лучше» _ – wilhelmtell

0

Dev-C++ использует старую версию компилятора MinGW. Используя новую версию GCC из проекта MinGW, который поддерживает расширенные списки инициализатора особенность C++ 0x (в частности серии GCC 4.4) следует сетовать с предупреждением о строках, которые помечены как ошибочные:

testing.cc:14: warning: extended списки инициализаторов доступны только с -std = C++ 0x или -std = gnu ++ 0x testing.cc:15: warning: extended списки инициализаторов доступны только с -std = C++ 0x или -std = gnu ++ 0x testing.cc:16: warning: extended списки инициализаторов доступны только с -std = C++ 0x или -std = gnu ++ 0x

Моя версия gcc 4.4.3 все равно жаловалась ... Не уверен в твоем.

Смежные вопросы