std::make_unique()
(और समान कार्य) के लिए make_unique/make_shared/क़ायम करना/आदि में अतिरिक्त कदम से बचना है एक छोटे से problem:संरचनाओं कि कुल आरंभीकरण का उपयोग
#include <cstdio>
#include <memory>
using namespace std;
struct S
{
S() { printf("ctor\n"); }
~S() { printf("dtor\n"); }
S(S const&) { printf("cctor\n"); }
S(S&&) { printf("mctor\n"); }
};
S foo() { return S(); }
int main()
{
{
printf("--------------- case 1 ---------------\n");
unique_ptr<S> s1 = make_unique<S>(foo());
}
{
printf("--------------- case 2 ---------------\n");
unique_ptr<S> s2 { new S(foo()) };
}
}
आउटपुट:
--------------- case 1 ---------------
ctor
mctor
dtor
dtor
--------------- case 2 ---------------
ctor
dtor
जैसा कि आप देख हमारे पास एक अतिरिक्त कदम है जिसे टाला जा सकता है। Same समस्या वैकल्पिक/संस्करण/आदि में emplace()
के साथ मौजूद है - यदि ऑब्जेक्ट अन्य फ़ंक्शन द्वारा लौटाया जाता है, तो आपको इसे स्थानांतरित करना होगा।
यह एक चाल के साथ addressed हो सकता है:
#include <cstdio>
#include <optional>
using namespace std;
struct S
{
S() { printf("ctor\n"); }
~S() { printf("dtor\n"); }
S(S const&) { printf("cctor\n"); }
S(S&&) { printf("mctor\n"); }
template<class F, enable_if_t<is_same_v<invoke_result_t<F>, S>>...>
S(F&& f) : S(forward<F>(f)()) {}
};
S foo() { return S(); }
int main()
{
optional<S> s;
s.emplace([]{ return foo(); });
}
यह अनावश्यक कदम से बचा जाता है (enable_if खाल निर्माता जब तक f()
एस का एक उदाहरण देता है)। आप अपने निर्माण कार्य के लिए कॉल के माध्यम से std::variant
/std::optional
/आदि के अंदर अपने मूल्यों को प्रभावी ढंग से समाप्त कर देते हैं।
इस फिक्स में एक छोटी सी समस्या है - एक कन्स्ट्रक्टर जोड़ना कुल प्रारंभिक तोड़ता है। example देखें। अर्थात। अगर दिया संरचना कोई निर्माता था और आप एक जोड़ने - यदि आप अब इस तरह यह प्रारंभ कर सकते हैं:
struct D
{
float m;
S s;
// adding new constructor here will break existing bar() functions
};
D bar() { /*...lots of code with multiple return statements...*/ return {2.0, foo()}; }
प्रश्न: इस समस्या के चारों ओर एक रास्ता नहीं है? ऐसा कुछ जो नए रचनाकारों को पेश नहीं करता है ...
मैं अपने संरचनाओं को वैकल्पिक रूप से वैकल्पिक/भिन्न/साझा_ptr-block/etc में बिना किसी ब्रेकिंग (बल्कि गैर-तुच्छ) कोड को डालने के लिए सक्षम करना चाहता हूं जो उन्हें बनाता है।
आपके 'ऑपरेटर परिणाम 'में' & ',' const & 'और' && 'ओवरलोड होने के लिए एक छोटा सा मामूली लाभ हो सकता है। ध्यान दें कि इसमें एक छोटी सी गड़बड़ी है, जिसमें परिणामस्वरूप लालची सीटीआर रूपांतरण ऑपरेटर को मौका दिए बिना कारखाने का उपभोग कर सकता है, लेकिन कुल मिलाकर समस्या नहीं है। – Yakk
'invoke_result_t' (या 'वापसी std :: move (f)(); ', आपका चयन।) –
@ टी.सी. मैं सिंगल-कैरेक्टर एडिट लेगा :) – Barry