As a follow up of this question, I tested the behavior of both clang and gcc. It appears that the two compiler have a different interpretation of the c++ standard.
In the example below, GCC refuses to compile, if a non copyable argument would need to be copied according to the deduction guide hypothetical constructor argument. Clang does not perform this check:
#include <cstddef>
struct not_copyable{
not_copyable()=default;
not_copyable(const not_copyable&)=delete;
};
struct movable{
movable()=default;
movable(movable&&);
};
template <typename T, size_t N>
struct A
{ template <typename ... Ts> A (Ts const & ...) {} };
template <typename T, size_t N>
struct B
{ template <typename ... Ts> B (const Ts & ...) {} };
template <typename T, typename ... Ts>
A(T const &, Ts const & ...) -> A<T, 1U + sizeof...(Ts)>;
template <typename T, typename ... Ts>
B(T, Ts ...) -> B<T, 1 + sizeof...(Ts)>;
int main()
{
not_copyable nc;
movable m;
auto a0 = A{nc}; // gcc & clang -> compile
auto a1 = A{m}; // gcc & clang -> compile
auto b0 = B{nc}; // clang ->compile; gcc -> error
auto b1 = B{m}; // clang ->compile; gcc -> error
}
In think the right behavior is defined in this paragraph of the C++ standard [over.match.class.deduct]/2:
Initialization and overload resolution are performed as described in [dcl.init] and [over.match.ctor], [over.match.copy], or [over.match.list] (as appropriate for the type of initialization performed) for an object of a hypothetical class type, where the selected functions and function templates are considered to be the constructors of that class type for the purpose of forming an overload set,[...]
I emphasized "for the purpose of forming an overload set" because I think this is where clang and gcc diverge. Clang does not seem to check if the deduction guide hypothetical constructor is a viable function, but gcc does. Which compiler is right?