如何用std :: bind()创建数据成员?

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)

但是,如何将所有三个对象作为数据成员放在一个类中呢?我可以简单地编写generatordistribution作为数据成员,但是如何在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中产生错误.

Cas*_*sey 7

你总是可以喘气写一个函数,而不是使用一个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成员声明可能不是不可能的.