- #include <utility> 
- #include <iostream> 
- #include <memory> 
-   
-   
- template<class T> 
- struct moved_value{ 
-     moved_value(T* v):pval(v){}; 
-   
- 	T& get(){return *pval;} 
- 	const T& get()const{return *pval;} 
-   
- private: 
- 	T* pval; 
-   
- }; 
- // Copied with removal of Parameter info from  
- // http://stackoverflow.com/questions/7943525/is-it-possible-to-figure-out-the-parameter-type-and-return-type-of-a-lambda 
-   
-   
- template <typename T> 
- struct function_traits 
-     : public function_traits<decltype(&T::operator())> 
- {}; 
- // For generic types, directly use the result of the signature of its 'operator()' 
-   
- template <typename ClassType, typename ReturnType, typename... Args> 
- struct function_traits<ReturnType(ClassType::*)(Args...) const> 
- // we specialize for pointers to member function 
- { 
-     typedef ReturnType result_type; 
-   
- }; 
-   
- template<class T,class F> 
- struct move_lambda{ 
- 	T val; 
- 	F f_; 
-   
- 	typedef function_traits<F> traits; 
- 	typedef typename traits::result_type result_type; 
-   
-   
-   
- 	move_lambda(T&& v, F f):val(std::move(v)),f_(f){}; 
- 	move_lambda(move_lambda&& other):val(std::move(other.val)),f_(std::move(other.f_)){} 
-   
- 	move_lambda& operator=(move_lambda&& other){ 
- 		val = std::move(other.val); 
- 		f_ = std::move(other.f_); 
-   
- 	} 
-   
- 	template<class... Args> 
- 	auto operator()(Args&& ...args) -> result_type 
- 	{ 
- 	    moved_value<T> mv(&val); 
- 		return f_(mv,std::forward<Args>(args)...); 
-   
- 	} 
-   
-   
-   
- private: 
- 	move_lambda(); 
- 	move_lambda(const move_lambda&); 
- 	move_lambda& operator=(const move_lambda&); 
-   
-   
-   
-   
- }; 
-   
- template<class T,class F> 
- move_lambda<T,F>create_move_lambda(T&& t, F f){ 
- 	return move_lambda<T,F>(std::move(t),f); 
- } 
-   
- // Unfortunately, std::function does not seem to support move-only callables 
- // Here is our quick movable replacement 
- template< class ReturnType, class... ParamTypes> 
- struct movable_function_base{ 
- 	virtual ReturnType callFunc(ParamTypes&&... p) = 0; 
-   
- }; 
-   
-   
- template<class F, class ReturnType, class... ParamTypes> 
- struct movable_function_imp:public movable_function_base<ReturnType,ParamTypes...>{ 
- 		F f_; 
- 	virtual ReturnType callFunc(ParamTypes&&... p){ 
- 		return f_(std::forward<ParamTypes>(p)...); 
- 	} 
-   
- 	explicit movable_function_imp(F&& f):f_(std::move(f)){}; 
-   
-   
-   
- private: 
- 	movable_function_imp(); 
- 	movable_function_imp(const movable_function_imp&); 
- 	movable_function_imp& operator=(const movable_function_imp&); 
- }; 
-   
-   
- template<class FuncType> 
- struct movable_function{}; 
-   
- template<class ReturnType, class... ParamTypes> 
- struct movable_function<ReturnType(ParamTypes...)>{ 
- 	std::unique_ptr<movable_function_base<ReturnType,ParamTypes...>> ptr_; 
-   
- 	template<class F> 
- 	explicit movable_function(F&& f):ptr_(new movable_function_imp<F,ReturnType,ParamTypes...>(std::move(f))){} 
- 	movable_function(movable_function&& other):ptr_(std::move(other.ptr_)){} 
- 	movable_function& operator=(movable_function&& other){ 
- 		ptr_ = std::move(other.ptr_); 
- 		return *this; 
- 	} 
-   
- 	template<class... Args> 
- 	auto operator()(Args&& ...args) -> ReturnType 
- 	{ 
- 	    return ptr_->callFunc(std::forward<Args>(args)...); 
-   
- 	} 
- private: 
- 	movable_function(); 
- 	movable_function(const movable_function&); 
- 	movable_function& operator=(const movable_function&); 
-   
- }; 
-   
-   
-   
-   
- struct TestMove{ 
- 	TestMove():k(0){} 
- 	TestMove(TestMove&& other):k(other.k){ 
- 		other.k = -1; 
- 	} 
- 	TestMove& operator=(TestMove&& other){ 
- 		k = other.k; 
- 		other.k = -1; 
- 		return *this; 
- 	} 
-   
- 	int k; 
- private: 
- 	TestMove(const TestMove&); 
- 	TestMove& operator=(const TestMove&); 
-   
-   
- }; 
-   
- movable_function<void()> CreateLambda() 
-   
- { 
-    typedef TestMove HugeObject; 
-    HugeObject hugeObj; 
-    hugeObj.k = 9; 
-   
-     // ...preparation of hugeObj... 
-   
-   
-    auto f = create_move_lambda(std::move(hugeObj),[](moved_value<HugeObject> hugeObj){// manipulate huge object 
- 		std::cout << hugeObj.get().k << std::endl; 
-   
-    }); 
-   
-   movable_function<void()> toReturn(std::move(f)); 
-   
-   return toReturn; 
-   
- } 
-   
-   
- int main(){ 
-   
- 	// A movable only type, not copyable 
- 	TestMove m; 
- 	m.k = 5; 
-   
- 	// A movable only type, not copyable 
- 	TestMove m2; 
- 	m2.k = 6; 
-   
- 	// Create a lambda that takes 2 parameters and returns int 
- 	auto lambda = create_move_lambda(std::move(m),[](moved_value<TestMove> m,int i,int)->int{std::cout << m.get().k << " " << i << std::endl;return 7;}); 
-   
- 	// Create a lambda that takes 0 parameters and returns void 
- 	auto lambda2 = create_move_lambda(std::move(m2),[](moved_value<TestMove> m){std::cout << m.get().k << std::endl;}); 
-   
-   
- 	std::cout <<  lambda(1,2) << std::endl; 
-   
- 	lambda2(); 
-   
-   
-   
-   
- 	// Compiler error if you try to copy 
- 	//auto lambda4 = lambda; 
-   
- 	// Able to move 
- 	auto lambda3 = std::move(lambda2); 
- 	lambda3(); 
-   
- 	auto lambda4 = CreateLambda(); 
-   
- 	lambda4(); 
-   
- } 
-