1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -emit-llvm-only %s
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fdelayed-template-parsing %s
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fms-extensions %s
// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only -fdelayed-template-parsing -fms-extensions %s
template<class T, class U> struct is_same { enum { value = false }; };
template<class T> struct is_same<T, T> { enum { value = true }; };
namespace test_sfinae_and_delete {
namespace ns1 {
template<class T> double f(T) = delete; //expected-note{{candidate}}
char f(...); //expected-note{{candidate}}
static_assert(is_same<decltype(f(3)),char>::value, ""); //expected-error{{call to deleted function}} expected-error{{static_assert failed}}
template<class T> decltype(f(T{})) g(T); // this one sfinae's out.
template<class T> int *g(T);
void foo() {
int *ip = g(3);
}
} //end ns1
namespace ns2 {
template<class T> double* f(T);
template<> double* f(double) = delete;
template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}
void foo() {
double *dp = g(3); //expected-error{{ambiguous}}
int *ip = g(3.14); // this is OK - because the explicit specialization is deleted and sfinae's out one of the template candidates
}
} // end ns2
namespace ns3 {
template<class T> double* f(T) = delete;
template<> double* f(double);
template<class T> decltype(f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}
void foo() {
int *dp = g(3); // this is OK - because the non-double specializations are deleted and sfinae's out one of the template candidates
double *ip = g(3.14); //expected-error{{ambiguous}}
}
} // end ns3
} // end ns test_sfinae_and_delete
namespace test_explicit_specialization_of_member {
namespace ns1 {
template<class T> struct X {
int* f(T) = delete;
};
template<> int* X<int>::f(int) { }
template<class T> decltype(X<T>{}.f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}
void foo() {
int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
int *ip = g(3); //expected-error{{ambiguous}}
}
} // end ns1
namespace ns2 {
struct X {
template<class T> double* f(T) = delete;
};
template<> double* X::f(int);
template<class T> decltype(X{}.f(T{})) g(T); // expected-note{{candidate}}
template<class T> int *g(T); //expected-note{{candidate}}
void foo() {
int *ip2 = g(3.14); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
int *ip = g(3); //expected-error{{ambiguous}}
}
} // end ns2
namespace ns3 {
template<class T> struct X {
template<class U> double *f1(U, T) = delete;
template<class U> double *f2(U, T) = delete;
};
template<> template<> double* X<int>::f1(int, int);
template<> template<class U> double* X<int>::f2(U, int);
template<class T, class U> decltype(X<T>{}.f1(U{}, T{})) g1(U, T); // expected-note{{candidate}}
template<class T, class U> int *g1(U, T); //expected-note{{candidate}}
template<class T, class U> decltype(X<T>{}.f2(U{}, T{})) g2(U, T); // expected-note2{{candidate}}
template<class T, class U> int *g2(U, T); //expected-note2{{candidate}}
void foo() {
int *ip2 = g1(3.14, 3); // this is OK - because the non-int specializations are deleted and sfinae's out one of the template candidates
int *ip = g1(3, 3); //expected-error{{ambiguous}}
{
int *ip3 = g2(3.14, 3); //expected-error{{ambiguous}}
int *ip4 = g2(3, 3); //expected-error{{ambiguous}}
}
{
int *ip3 = g2(3.14, 3.14);
int *ip4 = g2(3, 3.14);
}
}
} // end ns3
namespace ns4 {
template < typename T> T* foo (T);
template <> int* foo(int) = delete;
template <> int* foo(int); //expected-note{{candidate}}
int *IP = foo(2); //expected-error{{deleted}}
double *DP = foo(3.14);
} //end ns4
namespace ns5 {
template < typename T> T* foo (T);
template <> int* foo(int); //expected-note{{previous}}
template <> int* foo(int) = delete; //expected-error{{deleted definition must be first declaration}}
} //end ns5
} // end test_explicit_specializations_and_delete
|