Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Distribution as member of class in C++

I have two related questions concerning the use of distributions inside classes.

  1. Is there some kind of base distribution in C++ in order to use a distribution as a class member without knowing which distribution it will be? I cannot use templates (see question 2)

    class Foo{
        private:
            // could by any distribution
            std::base_distribution dist_;
    
    };
    
  2. I have another class Bar that should have a vector of Foo as a private member (std::vector<Foo>). The problem is that if Foo uses templates, then it is not possible to have a vector of different template arguments which is exactly what I want to have.

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

boost::variant doesn't help either because I don't know the type of distributions. So this (for example) is not possible in my case:

class Bar{
    private:
        boost::variant<std::normal_distribution<>, std::uniform_real_distribution<> > dists_;
};
like image 604
beginneR Avatar asked Feb 13 '17 12:02

beginneR


1 Answers

No, there are no base classes shared by all distribution templates. Even if there were, your intended approach wouldn't work anyway because of object slicing.

However, it should be fairly easy to create your own base class, and derive from it.

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...> {};

... and so on, for whatever distributions you want to support. You will also probably need to delegate the wrappers' constructors to their real distribution base class, for maximum transparency.

At this point, object slicing becomes a factor, so you can't just shove a base_distribution into a class, as a member, or shove it into a vector, and expect it to work. You'll have to use, at very least a

std::shared_ptr<base_distribution>

as a class member, or a container value. At this point, to wrap this up, define whatever virtual methods you need in your base_distribution class, and implement them in the template subclasses appropriately.

like image 118
Sam Varshavchik Avatar answered Oct 19 '22 20:10

Sam Varshavchik