2017-02-13 20 views
5

Mam dwa powiązane pytania dotyczące wykorzystania dystrybucji wewnątrz klas.Dystrybucja jako członek klasy w C++

  1. Czy istnieje jakiś rodzaj dystrybucji bazowej w C++, w celu korzystania z dystrybucji jako członka klasy bez znajomości których dystrybucja będzie? Nie mogę korzystać z szablonów (patrz pytanie 2)

    class Foo{ 
        private: 
         // could by any distribution 
         std::base_distribution dist_; 
    
    }; 
    
  2. mam inną klasę Bar które powinny mieć wektor Foo jako prywatny członka (std::vector<Foo>). Problem polega na tym, że jeśli Foo używa szablonów, to nie jest możliwe posiadanie wektora różnych argumentów szablonu, który jest dokładnie tym, co chcę mieć.

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

boost::variant nie pomaga, bo nie wiem, rodzaj dystrybucji. Więc to (na przykład) nie jest to możliwe w moim przypadku:

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

Jeśli potrzebujesz tylko jednego rodzaju silnika losowego, funkcja 'std :: function 'może być wystarczająca. –

Odpowiedz

8

Nie, nie ma klas podstawowych współużytkowanych przez wszystkie szablony dystrybucji. Nawet gdyby tak było, twoje zamierzone podejście i tak by nie zadziałało. because of object slicing.

Należy jednak dość łatwo utworzyć własną klasę bazową i wyprowadzić z niej.

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

... i tak dalej, niezależnie od dystrybucji, którą chcesz wspierać. Prawdopodobnie będziesz także musiał przekazać konstruktorów owijaczy do ich rzeczywistej klasy bazowej dystrybucji, dla maksymalnej przejrzystości.

W tym miejscu podział na obiekty staje się czynnikiem, więc nie można po prostu wepchnąć base_distribution do klasy, jako członka lub wepchnąć go do wektora i oczekiwać, że zadziała. Będziesz musiał użyć co najmniej jako członka klasy lub wartości kontenera. W tym momencie, aby zakończyć tę operację, zdefiniuj dowolne wirtualne metody, które potrzebujesz w swojej klasie base_distribution i odpowiednio zaimplementuj w podklasach szablonów.

+0

Możliwe, że będziesz mógł używać 'std :: unique_ptr '. –

+0

@MartinBonner To oczywiście wymaga podania klasy bazowej wirtualnego destruktora. –

+0

To robi.Ciągle zapominam, że jeden z inteligentnych wskaźników może przechwycić typ obiektu w czasie budowy, a następnie poprawnie go usunąć, nawet jeśli ostatni wskaźnik jest typu Base, a destruktor nie jest wirtualny. Musiałbym to sprawdzić, aby upewnić się, że był to "shared_ptr" - ale wirtualny destruktor jest zawsze bezpiecznym rozwiązaniem. –

1

O ile mi wiadomo, nie ma „class dystrybucja baza” lub rodzajowy klasy dystrybucji, w C++. Masz numer RandomNumberDistribution concept, ale to oczywiście nie to samo.

Jeśli chcesz szybko i brudną klasę dystrybucji (i mam na myśli brudną), obecnie używam czegoś takiego (.h, .cpp).

Jeśli chodzi o drugie pytanie, może być konieczne, aby klasa szablonowa dziedziczyła z pojedynczej niesformowanej klasy, którą można umieścić w wektorze (należy jednak użyć wskaźników, aby uniknąć przecinania danych).

+0

@MartinBonner: Właśnie o to mi chodziło. Pomyłkowo niech to brzmi jak sugestia. Dzięki. – einpoklum

Powiązane problemy