2017-08-28 28 views
2

下面的代碼工作正常無法通過lambda中的值捕獲隨機分配和生成器?

#include <iostream> 
#include <random> 

int main() { 
    std::default_random_engine generator; 
    std::normal_distribution<double> distribution(5.0, 2.0); 
    std::vector<double> v(100); 

    std::generate(v.begin(), v.end(), [&]() { return distribution(generator); }); 

    return 0; 
} 

然而,改變拉姆達的捕獲列表[=][&, distribution][&, generator]原因

rand.cpp:9:59: error: no matching function for call to object of type 'const std::normal_distribution<double>' 
error: assigning to 'double' from incompatible type 'void' 

是否有一些類型的對象不能用價值捕獲拉姆達?

回答

3

看起來像std::normal_distribution<double>::operator()不是const。 所以,你必須mutable關鍵字添加到您的拉姆達:

std::generate(v.begin(), v.end(), [=]() mutable { 
    return distribution(generator); 
}); 

std::generate(v.begin(), v.end(), [&, distribution]() mutable { 
    return distribution(generator); 
}); 

這些都工作得不錯。

3

通常情況下,按值捕獲要求對象是可複製的。 std::default_random_generatorstd::normal_distribution都是可複製的,所以這不應該成爲一個問題。

Lambda captures are always const values or const references.隨機數生成本質上是有狀態的,所以被調用的operator()不能是常量,因爲它可能會修改對象狀態。錯誤消息隱含地報告說,沒有函數在const std::normal_distribution<double>上調用。

如果要修改所捕獲的對象,必須聲明的lambda作爲可變

#include <iostream> 
#include <random> 
#include <algorithm> 

int main() { 
    std::default_random_engine generator; 
    std::normal_distribution<double> distribution(5.0, 2.0); 
    std::vector<double> v(100); 

    std::generate(v.begin(), v.end(), [generator, distribution]() mutable { return distribution(generator); }); 

    return 0; 
} 
+0

感謝您的解釋,該錯誤信息只是有點難以理解。對於任何內置類型,總是使用'&'是好習慣嗎? – Edityouprofile

+0

@displayname - 這取決於,但是,在這種特殊情況下,你肯定不想處理'generator'的副本。 – rustyx