blob: f0f10f2ef4f1a8831ff2c211613e4d1db41620c8 [file] [log] [blame]
// PR c++/101904
// Verify we stop at the first bad argument conversion when considering a
// candidate during overload resolution.
template<class T>
struct A { typedef typename T::type type; };
struct B {
// A conversion function that always induces a hard error when instantiated.
template<class T> B(T, typename A<T>::type = 0);
};
struct C {
template<class T> void f(T, typename A<T>::type); // #1
template<class T> void f(T, T) const; // #2
static void g(int*, B); // #3
static void g(int, int); // #4
#if __cpp_ref_qualifiers
void h(B) &; // #5
void h(int) &&; // #6
#endif
};
int main() {
const C c;
// The bad conversion for the 'this' argument should preclude us from further
// considering the non-const #1 (which would have caused a hard error during
// instantiation). This behavior is essentially DR 1391 extended to the
// 'this' argument.
c.f(0, 0); // resolves to #2
c.f<int>(0, 0);
// Likewise for the bad conversion for the 1st argument in #3.
C::g(42, 42); // resolves to #4
#if __cpp_ref_qualifiers
// Likewise for the bad 'this' conversion in #5.
C().h(0); // resolves to #6
#endif
}
#if __cpp_concepts
// Test the same calls in a SFINAE context.
template<class T>
concept D = requires (const T t) {
t.f(0, 0);
t.template f<int>(0, 0);
T::g(42, 42);
T().h(0);
};
static_assert(D<C>);
// Test that when there's no strictly viable candidate and we're in a
// SFINAE context, we still stop at the first bad argument conversion.
template<class T>
concept E = requires { T().h(nullptr); };
static_assert(!E<C>);
#endif