2015-11-05 85 views
4

我想使兩個不同的載體包含自定義結構,但是當我嘗試向矢量添加元素時,它爲「deck」向量工作,但拋出「players」向量的錯誤。我是C++新手,無法弄清楚什麼是錯的。C++多重結構載體錯誤

這些都是它拋出的錯誤:

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11| 

error: no matching function for call to 'std::vector<BlackjackClass::player>::push_back(<brace-enclosed initializer list>)'| 

這是我使用的代碼:

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

class BlackjackClass { 

    private: 
     struct card 
     { 
       string label; 
       int value; 
       string suit; 
     }; 
     vector<card> deck; 

     struct player 
     { 
       string name; 
       int bankroll; 
       int default_bet = 5; 
     }; 
     vector<player> players; 

    public: 
     BlackjackClass() 
     { 
      // Works 
      deck.push_back({"Queen", 10, "Hearts"}); 
      // Doesn't Work 
      players.push_back({"Jim", 500, 5}); 

     } 
}; 

int main() 
{ 
    BlackjackClass Blackjack; 
} 
+0

愚蠢的問題,但你使用-std = C++ 11嗎? – desu

+0

我打開了-std = C++ 11,並且擺脫了警告,但我仍然收到第二個錯誤。 –

+0

@ Karl-scmaltz您是否嘗試過創建卡片對象然後push_back? – desu

回答

1

那是因爲你有default_bet的默認值。 刪除它,它會工作或建立目標明確地,而不是初始化列表

struct player 
    { 
      string name; 
      int bankroll; 
      int default_bet = 5; 
      player(string name_, int bankroll_, int default_bet_) 
      { 
       name=name_; 
       bankroll=bankroll_; 
       default_bet_=default_bet_; 
      } 
    }; 


    players.push_back(player("Jim", 500, 5)); 
+0

和/或使用構造函數。 –

1

我不知道你的編譯選項,但警告

warning: extended initializer lists only available with -std=c++11 or -std=gnu++11| 

使我得出結論,在C++ 11(初始化程序列表)未啓用。

但是不是那麼少,代碼不會編譯,因爲初始化列表顯然不能處理參數的默認值。在這種情況下,問題的根源是行:

int default_bet = 5; 

刪除默認值,使C++ 11,那麼你的代碼將工作。

1

的問題是不相關的向量在所有,但可以通過更簡單地看出以下幾點:

card c { "Queen", 10, "Hearts" }; // OK  (g++ -std=c++11) 
player p { "Jim", 500, 5 };   // Not OK (g++ -std=c++11) 

有一個叫集合初始化藉此聚集可以從brace-初始化的事情封閉的初始化程序列表,繞過構造函數。 但非聚合不具備此;它們只能由其構造函數初始化。 playercard都隱式生成了不帶參數的默認構造函數,就這些了。


你的編譯器似乎是治療card作爲骨料,但不player

在C++ 11這是正確的,從N3337 [dcl.init.aggr]/1:

聚集是沒有用戶提供的構造的陣列或一個類(第9節)( 12.1),非靜態數據成員(9.2),沒有私有或受保護的非靜態數據成員(第11章),沒有基類(第10章),也沒有虛擬函數(10.3)的支撐或等同初始化器。 。

在C++ 14(N3936)此

但是改變爲:

聚集是沒有用戶提供的構造的陣列或一個類(第9節)(12.1),無私或 受保護的非靜態數據成員(第11章),無基類(第10章)和無虛函數(10.3)。

的​​在代碼是一個撐 - 或等於初始值設定爲一個非靜態數據成員,所以我們可以看到,在C++ 11 player不是彙總,但在C + +14 player是一個聚合。

使用g ++進行測試時,我發現g ++ 5.1正確地實現了這種行爲 - 代碼被-std=c++11拒絕並被-std=c++14接受。但是,g ++ 4.9.2會拒絕使用-std=c++14的代碼,所以這將成爲該版本g ++中的編譯器錯誤。


結論:如果您可以訪問到g ++ 5.1(或另一個編譯器,其正確實現C++ 14),然後一個解決辦法是編譯代碼時使用的-std=c++14標誌。否則,你將不得不投入一些醜陋的解決方法。