यह एक संकलक त्रुटि में परिणाम नहीं करता है, लेकिन एक रनटाइम त्रुटि। गलत समय को मापने के बजाय, आपको एक अपवाद मिलता है जो स्वीकार्य भी हो सकता है।
जिस भी कंस्ट्रक्टर को आप संरक्षित करना चाहते हैं, उसे एक डिफ़ॉल्ट तर्क की आवश्यकता होती set(guard)है, जिसे कहा जाता है।
struct Guard {
Guard()
:guardflagp()
{ }
~Guard() {
assert(guardflagp && "Forgot to call guard?");
*guardflagp = 0;
}
void *set(Guard const *&guardflag) {
if(guardflagp) {
*guardflagp = 0;
}
guardflagp = &guardflag;
*guardflagp = this;
}
private:
Guard const **guardflagp;
};
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
विशेषताएं हैं:
Foo f() {
// OK (no temporary)
Foo f1("hello");
// may throw (may introduce a temporary on behalf of the compiler)
Foo f2 = "hello";
// may throw (introduces a temporary that may be optimized away
Foo f3 = Foo("hello");
// OK (no temporary)
Foo f4{"hello"};
// OK (no temporary)
Foo f = { "hello" };
// always throws
Foo("hello");
// OK (normal copy)
return f;
// may throw (may introduce a temporary on behalf of the compiler)
return "hello";
// OK (initialized temporary lives longer than its initializers)
return { "hello" };
}
int main() {
// OK (it's f that created the temporary in its body)
f();
// OK (normal copy)
Foo g1(f());
// OK (normal copy)
Foo g2 = f();
}
के मामले में f2, f3और वापसी की "hello"इच्छा नहीं हो सकती है। फेंकने से रोकने के लिए, आप कॉपी guardके स्रोत के बजाय अब हमें संरक्षित करने के लिए कॉपी के स्रोत को अस्थायी बना सकते हैं। अब आप यह भी देखें कि हमने ऊपर दिए गए बिंदुओं का उपयोग क्यों किया - यह हमें लचीला होने की अनुमति देता है।
class Foo {
public:
Foo(const char *arg1, Guard &&g = Guard())
:guard()
{ g.set(guard); }
Foo(Foo &&other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
Foo(const Foo& other)
:guard(other.guard)
{
if(guard) {
guard->set(guard);
}
}
~Foo() {
assert(!guard && "A Foo object cannot be temporary!");
}
private:
mutable Guard const *guard;
};
विशेषताओं के लिए f2, f3और return "hello"अब हमेशा के लिए हैं // OK।