1 | // RUN: %clang_cc1 -verify -std=c++1z %s |
2 | |
3 | namespace Explicit { |
4 | // Each notional constructor is explicit if the function or function template |
5 | // was generated from a constructor or deduction-guide that was declared explicit. |
6 | template<typename T> struct A { |
7 | A(T); |
8 | A(T*); |
9 | A(...); |
10 | }; |
11 | template<typename T> A(T) -> A<T>; |
12 | template<typename T> explicit A(T*) -> A<T**>; // expected-note {{explicit}} |
13 | |
14 | int *p; |
15 | A a(p); |
16 | A b = p; |
17 | A c{p}; |
18 | A d = {p}; // expected-error {{selected an explicit deduction guide}} |
19 | |
20 | using X = A<int**>; |
21 | using Y = A<int>; // uses the implicit guide, being more specialized than the eligible user-defined deduction guides. |
22 | |
23 | using X = decltype(a); |
24 | using Y = decltype(b); |
25 | using X = decltype(c); |
26 | } |
27 | |
28 | |
29 | namespace std { |
30 | template<typename T> struct initializer_list { |
31 | const T *ptr; |
32 | __SIZE_TYPE__ size; |
33 | initializer_list(); |
34 | }; |
35 | } |
36 | |
37 | namespace p0702r1 { |
38 | template<typename T> struct X { // expected-note {{candidate}} |
39 | X(std::initializer_list<T>); // expected-note {{candidate}} |
40 | }; |
41 | |
42 | X xi = {0}; |
43 | X xxi = {xi}; |
44 | extern X<int> xi; |
45 | // Prior to P0702R1, this is X<X<int>>. |
46 | extern X<int> xxi; |
47 | |
48 | struct Y : X<int> {}; |
49 | Y y {{0}}; |
50 | X xy {y}; |
51 | extern X<int> xy; |
52 | |
53 | struct Z : X<int>, X<float> {}; |
54 | Z z = {{0}, {0.0f}}; |
55 | // This is not X<Z> even though that would work. Instead, it's ambiguous |
56 | // between X<int> and X<float>. |
57 | X xz = {z}; // expected-error {{no viable constructor or deduction guide}} |
58 | } |
59 | namespace pr34970 { |
60 | //https://bugs.llvm.org/show_bug.cgi?id=34970 |
61 | |
62 | template <typename X, typename Y> struct IsSame { |
63 | static constexpr bool value = false; |
64 | }; |
65 | |
66 | template <typename Z> struct IsSame<Z, Z> { |
67 | static constexpr bool value = true; |
68 | }; |
69 | |
70 | template <typename T> struct Optional { |
71 | template <typename U> Optional(U&&) { } |
72 | }; |
73 | |
74 | template <typename A> Optional(A) -> Optional<A>; |
75 | |
76 | int main() { |
77 | Optional opt(1729); |
78 | Optional dupe(opt); |
79 | |
80 | static_assert(IsSame<decltype(opt), Optional<int>>::value); |
81 | static_assert(IsSame<decltype(dupe), Optional<int>>::value); |
82 | static_assert(!IsSame<decltype(dupe), Optional<Optional<int>>>::value); |
83 | return 0; |
84 | } |
85 | |
86 | |
87 | } |