【问题标题】:Distribution as member of class in C++作为 C++ 中的类成员分发
【发布时间】:2017-07-01 09:55:06
【问题描述】:

我有两个有关在类中使用分布的相关问题。

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

    class Foo{
        private:
            // could by any distribution
            std::base_distribution dist_;
    
    };
    
  2. 我有另一个类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_;
};

【问题讨论】:

  • 如果只需要支持一种随机数引擎,std::function 可能就足够了。

标签: c++ class c++11 boost distribution


【解决方案1】:

据我所知,C++ 中没有“基本分发类”或通用分发类。你确实有一个RandomNumberDistribution concept,但这显然不是一回事。

如果你想要一个快速而肮脏的分发类(我的意思是肮脏的),我目前使用类似的东西(.h.cpp)。

至于您的第二个问题 - 您可能需要让您的模板类继承自一个可以放置在向量中的非模板类(不过,您需要使用指针成员,以避免数据切片)。

【讨论】:

  • @MartinBonner:这就是我的意思。我错误地认为这听起来像是一个建议。谢谢。
【解决方案2】:

不,所有分发模板都没有共享基类。即使有,您的预期方法无论如何也行不通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 类中定义您需要的任何虚拟方法,并在模板子类中适当地实现它们。

【讨论】:

  • 你可以使用std::unique_ptr&lt;base_distribution&gt;
  • @MartinBonner 当然,这需要给基类一个虚拟析构函数。
  • 确实如此。我一直忘记其中一个智能指针可以在构造时捕获对象的类型,然后正确删除它,即使最后一个指针是 Base 类型并且析构函数是非虚拟的。我必须查看它以确保它是 shared_ptr - 但虚拟析构函数始终是安全的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-08-25
  • 1970-01-01
相关资源
最近更新 更多