Skip to content

Instantly share code, notes, and snippets.

@lvv
Created October 18, 2012 08:41
Show Gist options
  • Save lvv/3910503 to your computer and use it in GitHub Desktop.
Save lvv/3910503 to your computer and use it in GitHub Desktop.
#include <utility>
#include <iostream>
using namespace std;
template <typename T>
struct counter {
static int created, alive;
counter() {++created; ++alive; }
~counter() { --alive; }
};
template <typename T> int counter<T>::created =0;
template <typename T> int counter<T>::alive =0;
// test object
struct to : counter<to> {
to() : id(this->created) { std::cout << "ctor () *" << id << std::endl; }
to(const to& o) : id(this->created) { std::cout << "ctor (cT&) " << id << "(" << o.id << ")"<< std::endl; }
to(to&& o) : id(this->created) { std::cout << "ctor (T&&) " << id << "(" << o.id << ")"<< std::endl; o.id = -o.id; }
~to() { std::cout << "dtor ~" << id << std::endl; }
to& operator=(const to& o) { std::cout << "= cp " << id << " = " << o.id << std::endl; return *this; }
to& operator=(to&& o) { std::cout << "= mv " << id << " = " << o.id << std::endl; o.id = -o.id; return *this; }
int id = 0;
};
template<class T> void f(T&& t) { t.id+=100; }
/* extra copy from this, with gcc48 and clang32, -O3
template <class T>
T wrapper(T&& t) {
f (std::forward<T>(t));
return t;
}
*/
/* no copying, no prove of UB
template <class T>
T&& wrapper(T&& t) {
f (std::forward<T>(t));
return std::forward<T>(t);
}
*/
// Move CTOR is used
template <class T>
T wrapper(T&& t) {
f (std::forward<T>(t));
return std::forward<T>(t);
}
int main() {
to lo;
cout << "*** calling wrapper on Lvalue\n";
wrapper(lo);
cout << "*** calling wrapper on Rvalue\n";
auto&& r = wrapper(to());
// stack overwriting - trying to get bad bahavier from UB
int a[10000] = {0};
cout << r.id << endl;;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment