[英]How to std::bind() to create a data member?
我用C ++ 11很好的新生成器和發行版生成隨機值。 在一個函數中,它就像一個魅力,看起來像這樣:
void foo() {
mt19937 generator;
uniform_int_distribution<unsigned> distribution;
auto dice = bind(distribution, generator);
// dice() will now give a random unsigned value
}
但是,如何將所有三個對象作為數據成員放在一個類中呢? 我可以簡單地將generator
和distribution
編寫為數據成員,但是如何在不知道(或想知道)其確切類型的情況下使dice
成為數據成員? 這令人驚訝
class X {
mt19937 generator;
uniform_int_distribution<unsigned> distribution;
decltype(bind(distribution, generator)) dice;
};
產生錯誤error C2660: 'bind' : function does not take 2 arguments
在Visual Studio 2013 error C2660: 'bind' : function does not take 2 arguments
。
你總是可以喘氣寫一個函數,而不是使用一個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);
}
};
用於參數化生成器和/或分布類型以及使用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))
};
};
對不起,我嘲笑你試圖首先使用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));
};
鑒於最新的Concepts Lite論文建議在auto
可能看起來意味着“推斷類型,如果類型沒有為命名概念建模而形成錯誤的語言”的任何地方使用概念名稱,那么auto
成員聲明可能不是不可能的。
std::bind
的結果未指定:這意味着您無法在沒有類型推斷的情況下存儲其原始結果。 但是,您可以使用std::function
來封裝bind
的結果:
#include <functional>
std::function<unsigned()> dice(std::bind(distribution, generator));
auto result = dice();
編輯:正如上面所說的那樣,這顯然是Visual Studio的問題。 我可以確認這與VS2013一起編譯:
#include <functional>
#include <random>
using namespace std;
class X {
mt19937 generator;
uniform_int_distribution<unsigned> distribution;
std::function<unsigned()> dice;
public:
X() : dice(bind(distribution, generator)) {}
unsigned roll() { return dice(); }
};
但是將dice
的類型改為decltype(bind(distribution, generator))
會使整個事情失敗並伴隨着絢麗的色彩(即使它仍然適用於clang)。
它適用於GCC 。 我很確定這只是一個編譯器錯誤。 不幸的是,這意味着您必須咬下苦葯並使用其他答案中描述的解決方法之一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.