aby*_*s.7 2 c++ lambda move-semantics c++11
我想实现一个简单的运行时检查宏,所以它的工作方式如下:
CHECK(expr) << "Some problem!";
Run Code Online (Sandbox Code Playgroud)
我写了一个简化的日志记录类来做到这一点:
class Log {
public:
Log() = default;
Log(const Log&) = delete;
~Log() {
cout << this << " dtor" << endl;
cout << stream_.str() << endl;
}
template <class T>
Log& operator<<(const T& info) {
cout << this << " <<" << endl;
stream_ << info;
return *this;
}
private:
stringstream stream_;
};
Run Code Online (Sandbox Code Playgroud)
让宏观:
#define CHECK(expr) \
if (!(expr)) [] { /* See attempts below */ }()
Run Code Online (Sandbox Code Playgroud)
现在让我们尝试实现lambda.
最简单的方法应该是:
[] {
Log log;
log << "A";
return log;
}
Run Code Online (Sandbox Code Playgroud)
但没有运气 - 复制构造函数被删除:
error: use of deleted function 'Log::Log(const Log&)'
Run Code Online (Sandbox Code Playgroud)
好吧,让我们明确地移动局部变量:
[] {
Log log;
log << "A";
return move(log);
}
Run Code Online (Sandbox Code Playgroud)
嗯,还是没有运气.
一种绝望的尝试当然不应该起作用:
[]() -> Log&& {
Log log;
log << "A";
return move(log);
}
Run Code Online (Sandbox Code Playgroud)
它编译甚至运行,但是operator <<在析构函数之后调用:
0xbfe84064 dtor
A
0xbfe84064 <<
Run Code Online (Sandbox Code Playgroud)
帮我弄清楚从lambda返回一个变量我做错了什么?
制作移动构造函数default,即
Log(Log&&) = default;
Run Code Online (Sandbox Code Playgroud)
因为否则存在用户提供的复制ctor(即使deleted)禁用移动ctor.您也应该return log;代替return move(log);,因为默认移动ctor将被调用(因为复制ctor被删除).例如参见本关于为什么越来越多的信息return move一般应避免.
| 归档时间: |
|
| 查看次数: |
163 次 |
| 最近记录: |