i want implement simple runtime check macro, works like:
check(expr) << "some problem!";
i wrote simplified logging class so:
class log { public: log() = default; log(const log&) = delete; ~log() { cout << << " dtor" << endl; cout << stream_.str() << endl; } template <class t> log& operator<<(const t& info) { cout << << " <<" << endl; stream_ << info; return *this; } private: stringstream stream_; };
and let macro be:
#define check(expr) \ if (!(expr)) [] { /* see attempts below */ }()
now let's try implement lambda.
attempt #1
the simplest way should be:
[] { log log; log << "a"; return log; }
but no luck - copy constructor deleted:
error: use of deleted function 'log::log(const log&)'
attempt #2
ok, let's move local variable explicitly:
[] { log log; log << "a"; return move(log); }
hmm, still no luck.
attempt #3
a desperate attempt shouldn't work:
[]() -> log&& { log log; log << "a"; return move(log); }
it compiles , runs, operator <<
called after destructor:
0xbfe84064 dtor 0xbfe84064 <<
help me figure out doing wrong returning variable lambda?
make move constructor default
, i.e.
log(log&&) = default;
because otherwise existence of user-provided copy ctor (even if delete
d) disables move ctor. should return log;
instead of return move(log);
, default move ctor invoked (since copy ctor deleted). see e.g. this more details on why return move
should in general avoided.
Comments
Post a Comment