#include <iostream>
#include <iostream>

template<class... T>
struct non_copyable_type {
	non_copyable_type() = delete;
	non_copyable_type(const non_copyable_type&) = delete;
	non_copyable_type(const T&...) {};
};

using T1  = non_copyable_type<int>;
using T2  = T1;
using TL1 = non_copyable_type<T1, T2>;

using foo_t = non_copyable_type<T1, T2, TL1>;

template<class... Args>
void side_effects(Args&&... args) {
	std::cout << "side effects" << std::endl;
}
template<class... Args>
void second_side_effects(Args&&... args) {
	std::cout << "second side effects" << std::endl;
}
template<class... Args>
void final_side_effects(Args&&... args) {
	std::cout << "final side effects" << std::endl;
}

struct C {
	C(const T1& arg_1, const T2& arg_2) {
    		side_effects(arg_1, arg_2);
    		TL1 local_1(arg_1, arg_2);
    		second_side_effects(arg_1, arg_2, local_1);
    		foo_t f(arg_1, arg_2, local_1); // the actual construction
    		final_side_effects(arg_1, arg_2, local_1, f);
	}
};

struct C2 {
	C2(const T1& arg_1, const T2& arg_2)
	: C2(arg_1, arg_2
                ,([](const T1& a, const T2& b){
	             side_effects(a, b);
                }(arg_1, arg_2), TL1(arg_1, arg_2))) {}

	C2(const T1& arg_1, const T2& arg_2, TL1&& local_1)
	: C2(arg_1, arg_2
	    ,[](const T1& a, const T2& b, TL1& c) -> TL1& {
	            second_side_effects(a, b, c);
	            return c;
	    }(arg_1, arg_2, local_1)) {}

	C2(const T1& arg_1, const T2& arg_2, TL1& local_1)
	: f(arg_1, arg_2, local_1) {
	    final_side_effects(arg_1, arg_2, local_1, f);
	}
private:
	foo_t f;
};

int main() {
	T1 a(0);
	T2 b(0);
	C c1(a, b);
	C2 c2(a, b);
}