namespace N {
struct X {};
bool operator<=(X, X);
template<bool(X, X)> struct Y {};
Y<operator<=> y; // ill-formed; previously well-formed
}
struct A { // not an aggregate; previously an aggregate
A() = delete;
};
struct B { // not an aggregate; previously an aggregate
B() = default;
int i = 0;
};
struct C { // not an aggregate; previously an aggregate
C(C&&) = default;
int a, b;
};
A a{}; // ill-formed; previously well-formed
B b = {1}; // ill-formed; previously well-formed
auto* c = new C{2, 3}; // ill-formed; previously well-formed
struct Y;
struct X {
operator Y();
};
struct Y { // not an aggregate; previously an aggregate
Y(const Y&) = default;
X x;
};
Y y{X{}}; // copy constructor call; previously aggregate-initialization
struct S {
explicit (S)(const S&); // ill-formed; previously well-formed
explicit (operator int)(); // ill-formed; previously well-formed
explicit(true) (S)(int); // OK
};
template<class T>
struct A {
A<T>(); // error: simple-template-id not allowed for constructor
A(int); // OK, injected-class-name used
~A<T>(); // error: simple-template-id not allowed for destructor
};
struct A {};
bool operator<(void (*fp)(), A);
void f() {}
int main() {
A a;
f < a; // ill-formed; previously well-formed
(f) < a; // still well formed
}