xref: /llvm-project/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p3.cpp (revision 70f59b5bbc84d195b4c7ee1597dcae4e73d3c479)
1 // RUN: %clang_cc1 -std=c++1z -verify %s
2 
3 namespace std_example {
4   template <class T> struct A {
5     explicit A(const T &, ...) noexcept; // expected-note {{explicit}}
6     A(T &&, ...); // expected-note 2{{candidate}}
7   };
8 
9   int i;
10   A a1 = {i, i}; // expected-error {{class template argument deduction for 'A' selected an explicit constructor for copy-list-initialization}}
11   A a2{i, i};
12   A a3{0, i};
13   A a4 = {0, i};
14 
15   template <class T> A(const T &, const T &) -> A<T &>; // expected-note 2{{candidate}}
16   template <class T> explicit A(T &&, T &&) -> A<T>; // expected-note {{explicit deduction guide declared here}}
17 
18   // FIXME: The standard gives an incorrect explanation for why a5, a7, and a8 are ill-formed.
19   A a5 = {0, 1}; // expected-error {{class template argument deduction for 'A' selected an explicit deduction guide}}
20   A a6{0, 1};
21   A a7 = {0, i}; // expected-error {{ambiguous deduction}}
22   A a8{0, i}; // expected-error {{ambiguous deduction}}
23 
24   template <class T> struct B {
25     template <class U> using TA = T;
26     template <class U> B(U, TA<U>);
27   };
28   B b{(int *)0, (char *)0};
29 }
30 
31 namespace check {
32   using namespace std_example;
33   template<typename T, typename U> constexpr bool same = false;
34   template<typename T> constexpr bool same<T, T> = true;
35 
36   static_assert(same<decltype(a2), A<int>>);
37   static_assert(same<decltype(a3), A<int>>);
38   static_assert(same<decltype(a4), A<int>>);
39   static_assert(same<decltype(a6), A<int>>);
40   static_assert(same<decltype(b), B<char*>>);
41 }
42