2017-02-13 2 views
5

クラス内のディストリビューションの使用に関する2つの関連する質問があります。C++のクラスのメンバーとしての配布

  1. ディストリビューションをクラスメンバとして使用するために、ディストリビューションがどのディストリビューションであるかを知らないで、何らかの種類のディストリビューションディストリビューションがありますか?私はプライベートメンバ(std::vector<Foo>)としてFooのベクトルを持つべきである別のクラスBarを持って

    class Foo{ 
        private: 
         // could by any distribution 
         std::base_distribution dist_; 
    
    }; 
    
  2. (質問2を参照)、テンプレートを使用することはできません。問題は、Fooがテンプレートを使用する場合、まさに私が望むものである異なるテンプレート引数のベクトルを持つことはできないということです。

    class Bar { 
        private: 
         std::vector<Foo> foo_; 
    
    }; 
    

boost::variant私はディストリビューションの種類が分からないので、どちらか助けていません。したがって、この(たとえば)私の場合は不可能である。私の知る限り

class Bar{ 
    private: 
     boost::variant<std::normal_distribution<>, std::uniform_real_distribution<> > dists_; 
}; 
+0

一種の乱数エンジンをサポートすればよい場合は、 'std :: function'だけで十分です。 –

答えて

8

いいえ、すべての配布テンプレートで共有される基本クラスはありません。たとえあったとしても、意図した方法はとにかく動作しません。because of object slicing

ただし、独自の基本クラスを作成してそれから派生するのは簡単です。

class base_distribution {}; 

template<typename ...Args> class normal_distribution : 
public base_distribution, public std::normal_distribution<Args...> {}; 

template<typename ...Args> class uniform_int_distribution : 
public base_distribution, public std::inform_int_distribution<Args...> {}; 

...など、サポートしたいディストリビューションであれば、また、おそらく、透過性を最大限にするために、ラッパーのコンストラクタを実際の配布ベースクラスに委譲する必要があります。

この時点で、オブジェクトのスライスが要素になるため、base_distributionをクラスに、メンバーとして、またはベクトルに押し込んで動作させることはできません。少なくとも、

std::shared_ptr<base_distribution> 

をクラスメンバまたはコンテナ値として使用する必要があります。この時点で、これをまとめて、base_distributionクラスで必要な仮想メソッドを定義し、それらを適切にテンプレートのサブクラスに実装します。

+0

あなたは 'std :: unique_ptr 'を使うことができるかもしれません。 –

+0

@MartinBonnerこれはもちろん、基本クラスに仮想デストラクタを与える必要があります。 –

+0

です。最後のポインタの型がBaseでデストラクタが非仮想であっても、スマートポインタの1つが構築時にオブジェクトの型を取り込んで正しく削除できることを忘れています。私はそれが 'shared_ptr'であることを確かめるためにそれを調べなければならないだろうが、仮想デストラクタは常に安全な解決策である。 –

1

、何の「基本配布クラス」や、一般的なディストリビューションクラスはC++で、ありません。 RandomNumberDistribution conceptがありますが、それは明らかに同じものではありません。

クイックダーティーな配布クラスが必要な場合(汚いという意味です)、私は現在、そのようなもの(.h.cpp)を使用しています。

2番目の質問としては、テンプレート化されたクラスをベクターに入れることができる1つのテンプレート化されていないクラスから継承する必要があります(データスライシングを避けるためにポインタメンバーを使用する必要があります)。

+0

@MartinBonner:それは私が意味していたものです。私は誤ってそのような音を示唆のようにしました。ありがとう。 – einpoklum

関連する問題