दिलचस्प पोस्ट
प्रत्येक कारक स्तर के लिए 1/0 सूचक चर के संग्रह में एक आर कारक को स्वचालित रूप से विस्तारित करना JQuery का उपयोग करके एंकर के लिए पृष्ठ को ऊपर या नीचे कैसे स्क्रॉल करें? एक ही पंक्ति में उत्पादन पिछले आउटपुट को ओवरराइट कर रहा है? अजगर (2.5) PHP यदि कई शर्तों के साथ वक्तव्य जावास्क्रिप्ट में एक विशिष्ट ऑब्जेक्ट प्रोटोटाइप में JSON स्ट्रिंग को पार्स करें एक सरणी में डुप्लिकेट ढूंढें किसी मौजूदा प्रशंसक पेज के साथ फेसबुक ऐप को कैसे लिंक करें रेल। जहां बनाम अधिकतम स्टैक उपयोग का निर्धारण कैसे करें? Java.util.Scanner का उपयोग करके इनपुट की पुष्टि करना Mysql में group_concat के समान ओरेकल में कोई फ़ंक्शन है? एक स्थिति से मेल खाते, एक ऑरेंज के अंदर ऑब्जेक्ट का सूचक प्राप्त करें कोई भी स्रोत के साथ छवि को शामिल करने का मान्य तरीका क्या है? आइटम्स कंट्रोल में आइटम्स के बीच एक विभाजक कैसे जोड़ा जा सकता है सीएसएस कैल्श () फ़ंक्शन में एसएएस वैरिएबल

क्यों नहीं कोई डिफ़ॉल्ट हल-असाइनमेंट / चाल-कन्स्ट्रक्टर?

मैं एक साधारण प्रोग्रामर हूँ मेरे क्लास सदस्यों के चर में अक्सर पीओडी-प्रकार और एसटीएल-कंटेनरों होते हैं इस वजह से मुझे शायद ही कभी असाइनमेंट ऑपरेटर या प्रतिलिपि कन्स्ट्रक्टर लिखना है, क्योंकि ये डिफ़ॉल्ट रूप से लागू होते हैं।

इस में जोड़ें, यदि मैं std::move ऑब्जेक्ट्स पर std::move उपयोग नहीं करता है, तो यह असाइनमेंट ऑपरेटर का इस्तेमाल करता है, जिसका अर्थ है std::move पूरी तरह से सुरक्षित है I

जैसा कि मैं एक साधारण प्रोग्रामर हूं, मैं हर वर्ग के लिए this->member1_ = std::move(other.member1_);... निर्माता / असाइनमेंट ऑपरेटर को जोड़ने के बिना चाल-क्षमताओं का लाभ लेना चाहता हूं, क्योंकि कंपाइलर उन्हें " this->member1_ = std::move(other.member1_);... रूप में लागू कर सकता है this->member1_ = std::move(other.member1_);... "

लेकिन यह कम से कम दृश्य 2010 में नहीं है, क्या इसका कोई विशेष कारण है?

अधिक महत्वपूर्ण बात; क्या इसके आसपास पाने के लिए कोई रास्ता नहीं है?

अद्यतन: यदि आप GManNickG के जवाब में नीचे देखो तो वह इस के लिए एक महान मैक्रो प्रदान करता है। और अगर आपको नहीं पता था, यदि आप चाल-सिमेंटिक लागू करते हैं तो आप स्वैप सदस्य फ़ंक्शन को निकाल सकते हैं।

वेब के समाधान से एकत्रित समाधान "क्यों नहीं कोई डिफ़ॉल्ट हल-असाइनमेंट / चाल-कन्स्ट्रक्टर?"

चालन निर्माता और असाइनमेंट ऑपरेटरों की अंतर्निहित पीढ़ी विवादास्पद रही है और सी ++ मानक के हाल के मसौदे में बड़े संशोधन हुए हैं, इसलिए वर्तमान में उपलब्ध कंपाइलर्स अंतःस्थापित पीढ़ी के संबंध में अलग-अलग व्यवहार करेंगे।

इस मुद्दे के इतिहास के बारे में अधिक जानने के लिए, 2010 WG21 पत्रों की सूची देखें और "mov" के लिए खोज करें

वर्तमान विनिर्देश (N3225, नवंबर से) राज्यों (N3225 12.8 / 8):

अगर एक कक्षा X की परिभाषा स्पष्ट रूप से एक चालन निर्माता घोषित नहीं करती है, तो एक पर निहित रूप से घोषित किया जाएगा यदि और केवल तभी

  • X उपयोगकर्ता द्वारा घोषित प्रति कन्स्ट्रक्टर नहीं है, और

  • X उपयोगकर्ता-घोषित कॉपी असाइनमेंट ऑपरेटर नहीं है,

  • X उपयोगकर्ता-घोषित चाल असाइनमेंट ऑपरेटर नहीं है,

  • X कोई उपयोगकर्ता घोषित नाशक नहीं है, और

  • चालन निर्माता को नष्ट किए जाने के रूप में परिभाषित नहीं किया जाएगा

12.8 / 22 में इसी तरह की भाषा निर्दिष्ट होती है जब चालन असाइनमेंट ऑपरेटर को निस्तारण रूप से डिफ़ॉल्ट घोषित किया जाता है। आप एन 3203 में अंतर्निहित चालित पीढ़ी के मौजूदा विनिर्देशों को समर्थन देने के लिए किए गए परिवर्तनों की पूरी सूची पा सकते हैं : अंतर्निहित चालें पैदा करने की स्थिति को कस कर रही है , जो बड़े पैमाने पर बर्जने स्ट्रास्ट्रस के पेपर N3201: मूविंग राइट्स के साथ प्रस्तावित प्रस्तावों में से एक था।

स्पष्ट रूप से उत्पन्न चालन निर्माता मानक के लिए विचार किया गया है, लेकिन खतरनाक हो सकता है। डेव अब्राहम के विश्लेषण देखें

अंत में, हालांकि, मानक में चलने वाले कंसल्टेंट्स की अंतर्निहित पीढ़ी शामिल थी और असाइनमेंट ऑपरेटरों को स्थानांतरित किया गया था, हालांकि सीमाओं की काफी पर्याप्त सूची के साथ:

अगर एक कक्षा एक्स की परिभाषा स्पष्ट रूप से एक चालन निर्माता घोषित नहीं करती है, तो एक पर निहित रूप से घोषित किया जाएगा यदि और केवल तभी
– एक्स में उपयोगकर्ता द्वारा घोषित प्रति कन्स्ट्रक्टर नहीं है,
– एक्स में उपयोगकर्ता-घोषित कॉपी असाइनमेंट ऑपरेटर नहीं है,
– एक्स में उपयोगकर्ता-घोषित चाल असाइनमेंट ऑपरेटर नहीं है,
– एक्स में कोई उपयोगकर्ता घोषित नाशक नहीं है, और
– चालन निर्माता को नष्ट किए जाने के रूप में परिभाषित नहीं किया जाएगा।

यह काफी नहीं है, हालांकि इस कहानी को बहुत कुछ है। एक ctor घोषित किया जा सकता है, लेकिन अभी भी हटाए गए के रूप में परिभाषित किया गया है:

एक निहित-घोषित कॉपी / चाल निर्माता, इसकी कक्षा का एक इनलाइन सार्वजनिक सदस्य है। क्लास एक्स के लिए एक डिफॉल्ट कॉपी / स्थानांतरण कन्स्ट्रक्टर को एक्स के रूप में हटाए गए (8.4.3) के रूप में परिभाषित किया गया है:

– एक गैर-तुच्छ संबंधित कंस्ट्रक्टर और एक्स के साथ एक संस्करण सदस्य एक यूनियन-जैसी क्लास है,
– क्लास प्रकार एम (या उसकी सरणी) का एक गैर-स्टैटिक डाटा सदस्य जिसे कॉपी / कॉपी नहीं किया जा सकता क्योंकि अधिभार रिज़ॉल्यूशन (13.3), जैसा कि एम के संबंधित कन्स्ट्रक्टर पर लागू होता है, एक अस्पष्टता या एक फ़ंक्शन जो कि हटाए गए या अनुपयोगी है डिफॉल्ट कन्स्ट्रक्टर,
– एक प्रत्यक्ष या आभासी आधार वर्ग बी, जिसे कॉपी / स्थानांतरित नहीं किया जा सकता क्योंकि ओवरलोड रिज़ॉल्यूशन (13.3), जैसा कि बी के संबंधित कन्स्ट्रक्टर पर लागू होता है, एक अस्पष्टता या फ़ंक्शन जो डिलीटेड कन्स्ट्रक्टर से हटाया या अनुपलब्ध है,
– किसी भी प्रत्यक्ष या आभासी बेस क्लास या गैर-स्थिर डाटा सदस्य जो एक डिस्ट्रक्टर के साथ एक प्रकार का है जिसे हटाए गए या डिफॉल्ट कन्स्ट्रक्टर से अनुपलब्ध है,
– प्रतिलिपि कन्स्ट्रक्टर के लिए, रैवल्यू संदर्भ प्रकार का एक गैर-स्थिर डेटा सदस्य, या
– चालन निर्माता के लिए, एक गैर-स्थिर डेटा सदस्य या प्रत्यक्ष या आभासी मूल वर्ग जिसे एक चालन निर्माता नहीं है और तुच्छ नकल नहीं करता है

(अब के लिए, मैं बेवकूफ़ मैक्रो पर काम कर रहा हूं …)

हाँ, मैं उस मार्ग को भी चला गया यहां आपका मैक्रो है:

 // detail/move_default.hpp #ifndef UTILITY_DETAIL_MOVE_DEFAULT_HPP #define UTILITY_DETAIL_MOVE_DEFAULT_HPP #include <boost/preprocessor.hpp> #define UTILITY_MOVE_DEFAULT_DETAIL_CONSTRUCTOR_BASE(pR, pData, pBase) pBase(std::move(pOther)) #define UTILITY_MOVE_DEFAULT_DETAIL_ASSIGNMENT_BASE(pR, pData, pBase) pBase::operator=(std::move(pOther)); #define UTILITY_MOVE_DEFAULT_DETAIL_CONSTRUCTOR(pR, pData, pMember) pMember(std::move(pOther.pMember)) #define UTILITY_MOVE_DEFAULT_DETAIL_ASSIGNMENT(pR, pData, pMember) pMember = std::move(pOther.pMember); #define UTILITY_MOVE_DEFAULT_DETAIL(pT, pBases, pMembers) \ pT(pT&& pOther) : \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM( \ UTILITY_MOVE_DEFAULT_DETAIL_CONSTRUCTOR_BASE, BOOST_PP_EMPTY, pBases)) \ , \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM( \ UTILITY_MOVE_DEFAULT_DETAIL_CONSTRUCTOR, BOOST_PP_EMPTY, pMembers)) \ {} \ \ pT& operator=(pT&& pOther) \ { \ BOOST_PP_SEQ_FOR_EACH(UTILITY_MOVE_DEFAULT_DETAIL_ASSIGNMENT_BASE, BOOST_PP_EMPTY, pBases) \ BOOST_PP_SEQ_FOR_EACH(UTILITY_MOVE_DEFAULT_DETAIL_ASSIGNMENT, BOOST_PP_EMPTY, pMembers) \ \ return *this; \ } #define UTILITY_MOVE_DEFAULT_BASES_DETAIL(pT, pBases) \ pT(pT&& pOther) : \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM( \ UTILITY_MOVE_DEFAULT_DETAIL_CONSTRUCTOR_BASE, BOOST_PP_EMPTY, pBases)) \ {} \ \ pT& operator=(pT&& pOther) \ { \ BOOST_PP_SEQ_FOR_EACH(UTILITY_MOVE_DEFAULT_DETAIL_ASSIGNMENT_BASE, BOOST_PP_EMPTY, pBases) \ \ return *this; \ } #define UTILITY_MOVE_DEFAULT_MEMBERS_DETAIL(pT, pMembers) \ pT(pT&& pOther) : \ BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_TRANSFORM( \ UTILITY_MOVE_DEFAULT_DETAIL_CONSTRUCTOR, BOOST_PP_EMPTY, pMembers)) \ {} \ \ pT& operator=(pT&& pOther) \ { \ BOOST_PP_SEQ_FOR_EACH(UTILITY_MOVE_DEFAULT_DETAIL_ASSIGNMENT, BOOST_PP_EMPTY, pMembers) \ \ return *this; \ } #endif 

 // move_default.hpp #ifndef UTILITY_MOVE_DEFAULT_HPP #define UTILITY_MOVE_DEFAULT_HPP #include "utility/detail/move_default.hpp" // move bases and members #define UTILITY_MOVE_DEFAULT(pT, pBases, pMembers) UTILITY_MOVE_DEFAULT_DETAIL(pT, pBases, pMembers) // base only version #define UTILITY_MOVE_DEFAULT_BASES(pT, pBases) UTILITY_MOVE_DEFAULT_BASES_DETAIL(pT, pBases) // member only version #define UTILITY_MOVE_DEFAULT_MEMBERS(pT, pMembers) UTILITY_MOVE_DEFAULT_MEMBERS_DETAIL(pT, pMembers) #endif 

(मैंने असली टिप्पणियां निकाल दी हैं, जो लंबाई और दस्तावेजी हैं।)

आप पूर्ववर्ती सूची के रूप में अपनी कक्षा में बेस और / या सदस्यों को निर्दिष्ट करते हैं, उदाहरण के लिए:

 #include "move_default.hpp" struct foo { UTILITY_MOVE_DEFAULT_MEMBERS(foo, (x)(str)); int x; std::string str; }; struct bar : foo, baz { UTILITY_MOVE_DEFAULT_BASES(bar, (foo)(baz)); }; struct baz : bar { UTILITY_MOVE_DEFAULT(baz, (bar), (ptr)); void* ptr; }; 

और बाहर एक चालन-निर्माता और कदम-असाइनमेंट ऑपरेटर आता है।

(एक तरफ, अगर कोई जानता है कि मैं विवरण कैसे एक मैक्रो में जोड़ सकता है, तो यह तेज हो जाएगा।)

VS2010 ऐसा नहीं करता क्योंकि वे कार्यान्वयन के समय मानक नहीं थे