2017-08-10 68 views
0

下面是我的代碼,用於根據用戶定義的權重值生成隨機數。這一切都有效,直到我試圖讓數據類型成爲任何類型,例如雙,浮動。我沒有什麼經驗在實踐中實施,只能在教科書上閱讀。任何人都可以幫助我解決它嗎?模板類執行錯誤

感謝,

class WeightedRandom 
{ 
public: 
    template <class T1,class T2> 
    void setWeight(T1 i,T2 val) 
    { 
     m[i]=val; 
     total+=val; 
    } 
    void generator() 
    { 
     int val=rand()%total; 
     for (auto a:m) 
     { 
      if (val<a.second) 
      { 
       res[a.first]++; 
       break; 
      } 
      val-=a.second; 
     } 
    } 
    void print() 
    { 
     for (auto a:res) 
     { 
      cout<<a.first<<" "<<a.second<<endl; 
     } 
    } 
private: 
    template <class T1,class T2> 
    unordered_map<T1,T2> m; 
    template <class T3,class T4> 
    unordered_map<T3,T4> res; // object-count 
    int total=0; 
}; 

int main(int argc, const char * argv[]) 
{ 
    WeightedRandom WR; 
    WR.setWeight(1, 5); 
    WR.setWeight(2, 20); 
    WR.setWeight(3, 50); 
    WR.setWeight(4, 20); 
    WR.setWeight(5, 10); 
    int n=10000; 
    for (int i=0;i<n;++i) 
    { 
     WR.generator(); 
    } 
    WR.print(); 
    } 
+0

什麼是錯誤?順便說一句,在'total + = val;''val'是T2的時候,你有'int total'。 – Serge

+0

是原來的地方,現在所有的模板都是int嗎? –

回答

0

你只需要到模板類,允許總成爲模板類型。

#include<unordered_map> 
#include<iostream> 
#include<math.h> 
using namespace std; 
template<typename T1,typename T2> 
class WeightedRandom{ 
public: 
    void setWeight(T1 i,T2 val) 
    { 
     m[i]=val; 
     total+=val; 
    } 
    void generator() 
    { 
     T2 val= (T2) fmod(rand(),total); 
     for (auto a:m) 
     { 
      if (val<a.second) 
      { 
       res[a.first]++; 
       break; 
      } 
      val-=a.second; 
     } 
    } 
    void print() 
    { 
     for (auto a:res) 
     { 
      cout<<a.first<<" "<<a.second<<endl; 
     } 
    } 
private: 
    unordered_map<T1,T2> m; 
    unordered_map<T1,T2> res; // object-count 
    T2 total=0; 
}; 

int main(int argc, const char * argv[]) 
{ 
    WeightedRandom<int,double> WR; 
    WR.setWeight(1, 5.01); 
    WR.setWeight(2, 19.99); 
    WR.setWeight(3, 50.01); 
    WR.setWeight(4, 19.99); 
    WR.setWeight(5, 10.00); 
    int n=10000; 
    for (int i=0;i<n;++i) 
    { 
     WR.generator(); 
    } 
    WR.print(); 
} 

FMOD採取了一倍,所以如果它是一個整數或浮點數,它會被提升到雙,結果將投退下來,或者如果它是一個雙,投什麼都不做。你可能需要考慮增加一些檢查,以確保您可以使用雙/ float和char /短路/ INT /長,因爲用戶可能會使用一些類的權重,其將不會做出太大的意義:

... 
class WeightedRandom{ 
    static_assert(!is_same<T,bool>(),"type can't be a bool"); 
    static_assert(is_arithmetic<T>(),"type needs to be an arithmetic"); 
... 
+0

謝謝,奧斯汀。真的很有幫助。 – landlord1984

+0

沒問題,雖然現在我想到了。你一定需要這些檢查,因爲FMOD將無法對非算術,所以如果你有WeightedRandom 什麼 –

+0

你會得到一個神祕的錯誤消息,我想有一個錯誤的輸入,如:WR.setWeight(真,「A」);但斷言不會打印出來。看來WeightedRandom WR;已將bool類型轉換爲int。那麼,如果輸入錯誤,我應該如何使斷言有效。 – landlord1984