在 C++ 中作为 class 的成员分发

Distribution as member of class in C++

关于 classes 中分布的使用,我有两个相关问题。

  1. C++ 中是否有某种基本分布,以便在不知道它是哪个分布的情况下将分布用作 class 成员?我无法使用模板(参见问题 2)

    class Foo{
        private:
            // could by any distribution
            std::base_distribution dist_;
    
    };
    
  2. 我有另一个 class Bar 应该有一个向量 Foo 作为私有成员 (std::vector<Foo>)。问题是,如果 Foo 使用模板,那么就不可能有一个由不同模板参数组成的向量,这正是我想要的。

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

boost::variant 也无济于事,因为我不知道发行版的类型。所以这(例如)在我的情况下是不可能的:

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

据我所知,在 C++ 中没有 "base distribution class" 或通用分布 class。你确实有一个RandomNumberDistribution concept,但这显然不是一回事。

如果您想要 quick-and-dirty 分布 class(我的意思是脏),我目前使用类似的东西 (.h, .cpp)。

至于你的第二个问题 - 你可能需要让你的模板 class 继承自一个 non-templated class ,你可以将它放在你的向量中(你需要但是使用指针成员,以避免数据切片)。

不,没有所有分发模板共享的基础 classes。即使有,您的预期方法也不会奏效 because of object slicing

但是,创建您自己的基础 class 并从中派生应该相当容易。

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

...等等,对于您想要支持的任何发行版。您可能还需要将包装器的构造函数委托给它们的实际分发基础 class,以获得最大的透明度。

在这一点上,对象切片成为一个因素,所以你不能只是将 base_distribution 作为成员推入 class,或将其推入向量,并期望它上班。您至少要使用

std::shared_ptr<base_distribution>

作为 class 成员,或容器值。在这一点上,总结一下,在 base_distribution class 中定义您需要的任何虚拟方法,并在模板 subclasses 中适当地实现它们。