2017-08-10 4 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は、二重になりますので、それがintやfloat型だ場合、それは二重に昇格され、結果が戻って投げ落とされる、またはそれは、二重だ場合、キャストは何もしません。 はdouble/floatまたはchar/short/int/longのみを使用することを確認するためにいくつかのチェックを追加することを検討するとよいでしょう。

... 
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(true、 'a');しかし、アサーションは印刷されません。それはWeightedRandomのようです WR; bool型をintに変換しました。では、誤った入力があった場合、どのようにアサートを動作させるべきですか? – landlord1984

関連する問題