This is a continuation of std :: unordered_map <T, std :: unique_ptr <U โ gt; Copyable? GCC error?
So, imagine that we created the Container template class:
template<class T> class Container { T t; public: Container() = default; Container(const Container& other) : t(other.t) {} };
Unfortunately, is_copy_constructible for it gives true , even if T not constructive for copying:
static_assert(!std::is_copy_constructible<Container<std::unique_ptr<int>>>::value, "Copyable");
This statement is not suitable for the reasons described in the answer to the question above, also here is another answer to this question .
It looks like this can be fixed by creating a copy constructor template as follows:
template<class T> class Container { T t; public: Container() = default; template<typename U = void> Container(const Container& other) : t(other.t) {} };
This works in both GCC and clang ( static_assert no longer works).
Perfect demonstration
Questions:
From a standard point of view, is this the right way to make is_copy_constructible work? If so, how does adding a template affect the validity of the immediate context of variable initialization ( ยง20.9.4.3/6 )?
(optional) Are there any more correct or more intuitive ways to do this?
Note: declaring the default copy constructor also achieves this goal, but is not always possible.
UPDATE: Now I see that my solution is invalid because the copy constructor cannot be a template. This still leaves room for question 2.
UPDATE 2: I changed the code from ecatmur answer a bit to move the ugliness from Container and make it reusable:
struct unused;
(demo)
But still I'm not quite happy with this. For me, it looks like a flaw in the C ++ standard that such things do not work out of the box.