#include <iostream>
#include <type_traits>

template <std::size_t SIZE> class A
{
    char b[SIZE];

public:
	using const_buffer_t = const char (&)[SIZE];

	A()                               : b{} { std::cout << "size: " << SIZE << " ctor 1\n"; }
	A(const_buffer_t)                 : b{} { std::cout << "size: " << SIZE << " ctor 2\n"; }
	explicit A(const A&)              : b{} { std::cout << "size: " << SIZE << " ctor 4\n"; }
	
	template <typename T,
	  typename=typename std::enable_if<
	    std::is_same<typename std::remove_cv<T>::type, char>{}
	  >::type>
	A(T* const&)                      : b{} { std::cout << "size: " << SIZE << " ctor 3\n"; }

	template <std::size_t OTHER_SIZE>
	A(const char (&)[OTHER_SIZE])     : b{} { std::cout << "size: " << SIZE << " ctor 5\n"; }

	template <std::size_t OTHER_SIZE>
	explicit A(const A<OTHER_SIZE> &) : b{} { std::cout << "size: " << SIZE << " ctor 6\n"; }
};

int main()
{
	A<5> a("five");
	A<5> b("0123456789");
	A<9> c(a);
	A<5> d;
	A<5> e(d);
	A<9> f(d);
}
