void addDivisorFilter()
{
auto calc1 = computeSomeValue1();
auto calc2 = computeSomeValue2();
auto divisor = computeDivisor(calc1, calc2);
filters.emplace_back(
[&](int value) { return value%divisor == 0;}
); // 悬空引用!!!
filters.emplace_back(
[&divisor](int value) {return value%divisor == 0;}
); //悬空引用!!!
}
class Widget {
public:
...
void addFilter() const;
private:
int divisor;
};
void Widget::addFilter() const
{
filters.emplace_back(
[=](int value){ return value%divisor == 0; }
);
//编译器会将上面这行代码转换成
auto currentObjectPtr = this;
filters.emplace_back(
[currentObjectPtr](int value) {
return value%currentObjectPtr->divisor == 0;
}
);
}
using FilterContainer =
std::vector<std::function<bool(int)>>;
FilterContainer filters;
void doSomeWork()
{
auto pw = std::make_unique<Widget>();
pw->addFilter(); //使用隐式捕捉成员变量
...// 出错,pw被销毁,lambda表达式现在持有的是悬空指针
}
void Widget::addFilter() const
{
filters.emplace_back(
[divisor](int value) { return value%divisor == 0; }
); //错误,divisor不是局部变量
}
void Widget::addFilter() const
{
filters.emplace_back(
[ ](int value) { return value%divisor == 0; }
); //错误,默认捕捉无法捕捉非局部变量
}
void Widget::addFilter() const
{
auto divisorCopy = divisor;
filters.emplace_back(
[divisorCopy](int value) {
return value%divisorCopy == 0;
}
);
}
void Widget::addFilter() const
{
auto divisorCopy = divisor;
filters.emplace_back(
[=](int value) {
return value%divisorCopy == 0;
}
);
}
void Widget::addFilter() const
{
filters.emplace_back(
[divisor = divisor](int value) {
return value%divisor == 0;
});
//把Widget的divisor成员变量拷贝
//到lambda内部的成员变量divisor中
}
void addDivisorFilter()
{
static auto calc1 = computeSomeValue1();
static auto calc2 = computeSomeValue2();
static auto divisor = computeDivisor(calc1, calc2);
filters.emplace_back(
[=](int value) {
return value%divisor == 0;
});
//捕捉不到任何对象,但是可以在lambda内部
//使用这个静态对象,而且是按照引用而不是值来使用的
++divisor;
}
class Widget {
public:
...
bool isValidated() const;
bool isProcessed() const;
bool isArchived() const;
private:
...
};
auto pw = std::make_unique<Widget>();
...
auto func = [pw = std::move(pw)] {
return pw->isValidated() && pw->isArchived();
};
//在lambda类内部生成一个pw成员变量
//然后接管外部变量pw的右值
//or
auto func = [pw = std::make_unique<Widget>()] {
return pw->isValidated() && pw->isArchived();
};
//直接使用表达式返回的右值对lambda内部成员变量进行初始化
class IsValAndArch {
public:
using DataType = std::unique_ptr<Widget>;
explicit IsValAndArch(DataType&& ptr):
pw(std::move(ptr)) {}
bool operator()() const
{
return pw->isValidated() && pw->isArchived();
}
private:
DataType pw;
};
auto func = IsValAndArch(std::make_unique<Widget>());
std::vector<double> data;
...
auto func = std::bind(
[](const std::vector<double>& data) {...},
std::move(data));
auto func = std::bind(
[] (std::vector<double>& data) mutable {...},
std::move(data));
auto f = [](auto x) {return normalize(x); };
//编译器编译后是这样
class SomeCompilerGeneratedClassName {
public:
template<typename T>
auto operator()(T x) const
{
return normallize(x);
}
...
};
auto f = [](auto&& x) {
return normalize(std::forward<???>(x));
};
// ???应该填入x的类型,但是这个类型不是固定的
//且此处也不是模板函数
auto f = [](auto&& x) {
return normalize(std::forward<decltype(x)>(x);
};
//1,decltype推导x的类型A
//2.std::forward根据A推导模板参数类型T
auto f = [](auto&&... xs) {
return normalize(std::forward<decltype(xs)>(xs)...);
};
using Time = std::chrono::steady_clock::time_point;
enum class Sound {Beep, Siren, Whistle};
using Duration = std::chrono::steady_clock::duration;
void setAlarm(Time t, Sound s, Duration d);
//设置一个闹钟,在时间t以铃声s开始响,最长持续时间为d
auto setSoundL = [](Sound s){
using namespace std::chrono;
setAlarm(steady_clock::now() + hours(1), s, seconds(30));
};
using namespace std::chrono;
using namespace std::literals;
using namespace std::placeholders;
auto setSoundB = std::bind(setAlarm,
steady_clock::now() + 1h, _1, 30s);
auto setSoundB = std::bind(setAlarm,
std::bind(std::plus<>(),
std::bind(steady_clock::now),
1h), _1, 30s);
using namespace std::chrono;
using namespace std::placeholders;
auto setSoundB = std::bind(
setAlarm,
std::bind(
std::plus<steady_clock::time_point>(),
std::bind(steady_clock::now), hours(1)
),
_1,
seconds(30));
auto setSoundL = [](Sound s){
using namespace std::chrono;
setAlarm(steady_clock::now() + 1h, s, 30s);
//能够正确匹配
};
using SetAlarm3ParamType = void(*) (Time t, Sound s, Duration d);
auto setSoundB = std::bind(
static_cast<SetAlarm3ParamType>(setAlarm),
std::bind(
std::plus<>,
std::bind(steady_clock::now),
1h),
_1,
30s);
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。