簡體   English   中英

如何用std :: bind()創建數據成員?

[英]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
}

但是,如何將所有三個對象作為數據成員放在一個類中呢? 我可以簡單地將generatordistribution編寫為數據成員,但是如何在不知道(或想知道)其確切類型的情況下使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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM