// RUN: %clang_cc1 -verify -std=c++1z %s namespace Explicit { // Each notional constructor is explicit if the function or function template // was generated from a constructor or deduction-guide that was declared explicit. template struct A { A(T); A(T*); A(...); }; template A(T) -> A; template explicit A(T*) -> A; // expected-note {{explicit}} int *p; A a(p); A b = p; A c{p}; A d = {p}; // expected-error {{selected an explicit deduction guide}} using X = A; using Y = A; // uses the implicit guide, being more specialized than the eligible user-defined deduction guides. using X = decltype(a); using Y = decltype(b); using X = decltype(c); } namespace std { template struct initializer_list { const T *ptr; __SIZE_TYPE__ size; initializer_list(); }; } namespace p0702r1 { template struct X { // expected-note {{candidate}} expected-note {{implicit deduction guide}} X(std::initializer_list); // expected-note {{candidate template ignored: could not match 'std::initializer_list' against 'Z'}} \ // expected-note {{implicit deduction guide declared as 'template X(std::initializer_list) -> p0702r1::X'}} }; X xi = {0}; X xxi = {xi}; extern X xi; // Prior to P0702R1, this is X>. extern X xxi; struct Y : X {}; Y y {{0}}; X xy {y}; extern X xy; struct Z : X, X {}; Z z = {{0}, {0.0f}}; // This is not X even though that would work. Instead, it's ambiguous // between X and X. X xz = {z}; // expected-error {{no viable constructor or deduction guide}} } namespace pr34970 { //https://bugs.llvm.org/show_bug.cgi?id=34970 template struct IsSame { static constexpr bool value = false; }; template struct IsSame { static constexpr bool value = true; }; template struct Optional { template Optional(U&&) { } }; template Optional(A) -> Optional; int main() { Optional opt(1729); Optional dupe(opt); static_assert(IsSame>::value); static_assert(IsSame>::value); static_assert(!IsSame>>::value); return 0; } } namespace deduceTemplatedConstructor { template struct IsSame { static constexpr bool value = false; }; template struct IsSame { static constexpr bool value = true; }; template struct A { using value_type = T; A(value_type); A(const A&); A(T, T, int); template A(int, T, U); }; A x(1, 2, 3); // no-error static_assert(IsSame>::value); template A(T) -> A; A a(42); static_assert(IsSame>::value); A b = a; static_assert(IsSame>::value); template A(A) -> A>; A b2 = a; static_assert(IsSame>>::value); }