puh*_*acz 3 c++ lambda clang shared-ptr c++11
使用(yield ,这是我期望的)构建时,此代码打印0(没有优化)或666(在启用优化的情况下).当lambda通过通用引用传递时,问题就消失了.clang++ -std=c++11-O3666
仅供参考,GCC打印666我测试过的所有版本.
它是编译器错误还是代码不正确?
#include <memory>
#include <iostream>
template <typename T>
std::shared_ptr<void> onScopeExit(T f)
{
return std::shared_ptr<void>((void*)1, [&](void *) {
f();
});
}
struct A {
void f() {
auto scopeGuard = onScopeExit([&]() { i = 666; }); // [1]
// ... (some work)
} // (lambda [1] being ? called on scope exit)
int i = 0;
};
A a;
int main() {
a.f();
std::cout << a.i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
有问题的编译器是:
Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
Run Code Online (Sandbox Code Playgroud)
Nat*_*ica 11
您的代码具有未定义的行为.你f通过引用捕获onScopeExit但是一旦你shared_ptr从函数返回,删除器现在持有一个悬空引用f,因为f超出了范围.您需要做的是f按值捕获,然后您将没有悬空参考
template <typename T>
std::shared_ptr<void> onScopeExit(T f)
{
return std::shared_ptr<void>((void*)1, [=](void *) {
f();
});
}
struct A {
void f() {
auto scopeGuard = onScopeExit([&]() { i = 666; }); // [1]
// ... (some work)
} // (lambda [1] being ? called on scope exit)
int i = 0;
};
A a;
int main() {
a.f();
std::cout << a.i << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
82 次 |
| 最近记录: |