"g++47 (FreeBSD Ports Collection) 4.7.0 20111203 (experimental)" invokes the destructor of two instances of this class twice. Sample output (highlighting what I've now wasted a week on):
$ /tmp/t Constructed 0x7fffffffdb00: 24 other: 24: 0x7fffffffdb00 Copied 0x7fffffffdb00 to 0x7fffffffdb20 Constructed 0x7fffffffdb30: 42 orig: 42: 0x7fffffffdb30 Copied 0x7fffffffdb30 to 0x7fffffffda90 cpy: 42: 0x7fffffffda90 Copied 0x7fffffffdb20 to 0x7fffffffda80 Copied 0x7fffffffda90 to 0x7fffffffdac0 Copied 0x7fffffffda80 to 0x7fffffffdac4 lambda: 42: 0x7fffffffdac0 other_lambda: 24: 0x7fffffffdac4 Destroyed 0x7fffffffdac0 ****** Destroyed 0x7fffffffdac4 ****** Destroyed 0x7fffffffdac4 ****** Destroyed 0x7fffffffdac0 ****** Destroyed 0x7fffffffda80 Destroyed 0x7fffffffda90 Destroyed 0x7fffffffdb30 Destroyed 0x7fffffffdb20 Destroyed 0x7fffffffdb00With "g++ (GCC) 4.7.0 20120507 (Red Hat 4.7.0-5)" the extra destructor calls do not occur. The output is the same, except for two of the destructor calls (ignoring the differences in the pointer values).
In both cases, I'm using only -std=c++0x to compile the following. As far as I can tell, I'm capturing everything by value, and I can't see what's ill- formed here:
#include <iostream> #include <string> #include <type_traits> class sw { public: int s; sw(const int &sa) : s(sa) { std::cout << "Constructed " << this << ": " << s << std::endl; } ~sw() { std::cout << "Destroyed " << this << std::endl; } sw(const sw &o) : s(o.s) { std::cout << "Copied " << &o << " to " << this << std::endl; } sw &operator=(const sw &o) { s=o.s; std::cout << "Assigned " << &o << " to " << this << std::endl; return *this; } void identify(const std::string &str) const { std::cout << str << ": " << s << ": " << this << std::endl; } }; template<typename lambda2> void foo(sw &&orig, lambda2 &&lambda) { orig.identify("orig"); sw cpy(orig); cpy.identify("cpy"); lambda2 lambda_cpy(std::move(lambda)); [cpy, lambda_cpy] { cpy.identify("lambda"); lambda_cpy(); }(); } int main(int argc, char **argv) { sw other(24); other.identify("other"); foo(sw(42), [other] { other.identify("other_lambda"); }); return (0); }
Attachment:
pgpj8HZhsPNXt.pgp
Description: PGP signature