cxx*_*xxl 5 c++ member stdbind c++11
我用C++ 11很好的新生成器和发行版生成随机值.在一个函数中,它就像一个魅力,看起来像这样:
void foo() {
mt19937 generator;
uniform_int_distribution<unsigned> distribution;
auto dice = bind(distribution, generator);
// dice() will now give a random unsigned value
}
Run Code Online (Sandbox Code Playgroud)
但是,如何将所有三个对象作为数据成员放在一个类中呢?我可以简单地编写generator和distribution作为数据成员,但是如何在dice不知道(或想知道)其确切类型的情况下创建数据成员?这令人惊讶
class X {
mt19937 generator;
uniform_int_distribution<unsigned> distribution;
decltype(bind(distribution, generator)) dice;
};
Run Code Online (Sandbox Code Playgroud)
error C2660: 'bind' : function does not take 2 arguments在Visual Studio 2013中产生错误.
你总是可以喘气写一个函数,而不是使用一个lambda /绑定的/ etc:
class X {
mt19937 generator;
uniform_int_distribution<unsigned> distribution;
public:
auto dice() -> decltype(distribution(generator)) {
return distribution(generator);
}
// or alternatively
auto operator() () -> decltype(distribution(generator)) {
return distribution(generator);
}
};
Run Code Online (Sandbox Code Playgroud)
用于参数化生成器和/或分布的类型以及用于保持生成器的加值点,std::shared_ptr以便您可以使具有不同分布的多个对象共享相同的引擎.你最终还是想要一个构造函数来为种子生成器播种 - 理想情况下就是这样std::random_device{}().
或者,我认为您正在寻找的答案:
class X {
mt19937 generator{std::random_device{}()};
uniform_int_distribution<unsigned> distribution{1,6};
public:
decltype(bind(std::ref(distribution), std::ref(generator))) dice{
bind(std::ref(distribution), std::ref(generator))
};
};
Run Code Online (Sandbox Code Playgroud)
对不起,我嘲笑你试图bind在第一时间使用它:实际上你可以用C++ 11中的"无代码"来编写这个类.我们需要在C++ 17中获取类成员声明的类型推断,这可能是:
class X {
auto generator = mt19937{std::random_device{}()};
auto distribution = uniform_int_distribution<unsigned>{1,6};
public:
auto dice = bind(std::ref(distribution), std::ref(generator));
};
Run Code Online (Sandbox Code Playgroud)
鉴于最新的Concepts Lite论文建议在语言中的任何地方使用概念名称,其中auto可能看起来意味着"推断类型,如果类型不构成命名概念,则形式不正确",auto成员声明可能不是不可能的.