struct X {
X(); // default constructor
X(X&); // copy constructor with a non-const parameter
};
const X cx;
X x = cx; // error: X::X(X&) cannot copy cx into x
— end example
struct S {
template<typename T> S(T);
S();
};
S g;
void h() {
S a(g); // does not instantiate the member template to produce S::S<S>(S);
// uses the implicitly declared copy constructor
} — end exampleX::X(const X&)
X::X(X&)
struct X {
X();
X& operator=(X&);
};
const X cx;
X x;
void f() {
x = cx; // error: X::operator=(X&) cannot assign cx into x
} — end exampleX& X::operator=(const X&)
X& X::operator=(X&)
struct S {
int a;
S& operator=(const S&) = default;
};
struct S {
int a;
S& operator=(const S&) = default;
S& operator=(S&&) = default;
}; — end exampleX& X::operator=(X&&);
class Thing {
public:
Thing();
~Thing();
Thing(const Thing&);
};
Thing f() {
Thing t;
return t;
}
Thing t2 = f();
struct A {
void *p;
constexpr A(): p(this) {}
};
constexpr A g() {
A a;
return a;
}
constexpr A a; // well-formed, a.p points to a
constexpr A b = g(); // well-formed, b.p points to b
void g() {
A c = g(); // well-formed, c.p may point to c or to an ephemeral temporary
}
class Thing {
public:
Thing();
~Thing();
Thing(Thing&&);
private:
Thing(const Thing&);
};
Thing f(bool b) {
Thing t;
if (b)
throw t; // OK: Thing(Thing&&) used (or elided) to throw t
return t; // OK: Thing(Thing&&) used (or elided) to return t
}
Thing t2 = f(false); // OK: no extra copy/move performed, t2 constructed by call to f
struct Weird {
Weird();
Weird(Weird&);
};
Weird g() {
Weird w;
return w; // OK: first overload resolution fails, second overload resolution selects Weird(Weird&)
} — end example