我有一個std::vector<float> weights;
包含權重列表。我不知道在這個列表中,在運行該程序的某個階段之前會有什麼。我想要做在VS2013中初始化std :: discrete_distribution
std::discrete_distribution<> dist(weights.begin(),weights.end());
但是VS2013似乎沒有std :: discrete_distribution的構造函數來接受迭代器範圍。有什麼解決方法嗎?
我有一個std::vector<float> weights;
包含權重列表。我不知道在這個列表中,在運行該程序的某個階段之前會有什麼。我想要做在VS2013中初始化std :: discrete_distribution
std::discrete_distribution<> dist(weights.begin(),weights.end());
但是VS2013似乎沒有std :: discrete_distribution的構造函數來接受迭代器範圍。有什麼解決方法嗎?
比較cppreference.com和Microsoft reference爲std::discrete_distribution
:
這些是VS2013提供的構造函數:
discrete_distribution();
explicit discrete_distribution(
const param_type& par0
);
discrete_distribution(
initializer_list<double> IList
);
template<class Fn>
discrete_distribution(
size_t count,
double low,
double high,
Fn func
);
有缺少一個重要的構造,可能是因爲微軟的開發者沒有足夠的時間來執行它:
template< class InputIt >
discrete_distribution(InputIt first, InputIt last);
這意味着,除非文檔是inco完整的,你不能使用這個類的基於迭代器的構造函數。切換到另一個編譯器(如clang或g ++),或者等到這個特性實現。
現在的解決方法,你現在可以使用:
std::size_t i(0);
assert(!weights.empty()); // No weights would be very weird.
std::discrete_distribution<> dist(weights.size(),
0.0, // dummy!
0.0, // dummy!
[&weights,&i](double)
{
auto w = weights[i];
++i;
return w;
});
我希望至少lambda表達式的支持;-)重要的是通過參考捕捉i
,這樣它才能正確遞增。演示:http://ideone.com/nIBUts
這是爲什麼有效?我們使用這裏的構造函數是:
template< class UnaryOperation >
discrete_distribution(std::size_t count, double xmin, double xmax,
UnaryOperation unary_op);
的documentation on cppreference告訴我們,count
(在我們的例子weights.size()
),以及在xmin
和xmax
用於創建使用UnaryOperation
的權重。
我們是忽略xmin
和xmax
故意。作爲UnaryOperation
我們用拉姆達
[&weights,&i](double)
{
auto w = weights[i];
++i;
return w;
}
或
[&weights,&i](double)
{
return weights[i++];
}
如果你喜歡。
現在,我們是忽略該運算符的輸入值,只是返回我們的向量的第i個元素。我們通過引用來捕獲向量和索引以避免副本。
std::discrete_distribution<> dist(
weights.size(),
-0.5,
-0.5+weights.size(),
[&weights](size_t i)
{
return weights[i];
});
或迭代的術語:
//replacement code for: std::discrete_distribution<> dist(first, last);
auto first = weights.cbegin();
auto last = weights.cend();
auto count = std::distance(first, last);
std::discrete_distribution<> dist(
count,
-0.5,
-0.5+count,
[&first](size_t i)
{
return *std::next(first,i);
});
這避免了以捕獲一個可變i
變量。傳遞給lambda的參數可以用作索引。
也許我的問題不夠清楚 - 我知道VS2013缺少這個基於迭代器的構造函數。我正在尋找某種解決方法,這不僅僅是切換編譯器或等待。 – pighead10
@ pighead10看我的編輯。沿着這些線應該工作。我還沒有測試過它(在這臺機器上沒有編譯器)。 [更新]至少它編譯與g ++ - 4.7 – stefan
謝謝。你能解釋一下解決方法嗎? – pighead10