I want to implement a simple runtime check macro, so it works like:
CHECK(expr) << "Some problem!";
I wrote a simplified logging class to do so:
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_;
};
And let the macro be:
#define CHECK(expr) \
if (!(expr)) [] { /* See attempts below */ }()
Now let's try to implement the lambda.
Attempt #1
The simplest way should be:
[] {
Log log;
log << "A";
return log;
}
But no luck - the copy constructor is deleted:
error: use of deleted function 'Log::Log(const Log&)'
Attempt #2
Ok, let's move the local variable explicitly:
[] {
Log log;
log << "A";
return move(log);
}
Hmm, still no luck.
Attempt #3
A desperate attempt that certainly shouldn't work:
[]() -> Log&& {
Log log;
log << "A";
return move(log);
}
It compiles and even runs, but the operator <<
is called after destructor:
0xbfe84064 dtor
A
0xbfe84064 <<
Help me to figure out what am I doing wrong with returning a variable from lambda?