2012-01-14 19 views
10

जब तक कि मैं गलत नहीं हूं ऐसा लगता है कि या तो ठीक काम करता है - क्या एक दूसरे को पसंद करने का सबसे अच्छा अभ्यास कारण है?क्या मुझे cdors/असाइनमेंट ऑपरेटरों में std :: move या std :: आगे का उपयोग करना चाहिए?

उदाहरण:

struct A 
{ 
    A(){} 
    A(const A&){ std::cout << "A(const A&)\n"; } 
    A(A&&){ std::cout << "A(A&&)\n"; } 
}; 

struct B 
{ 
    B(){} 
    B(const B& right) : x(right.x){ std::cout << "B(const B&)\n"; } 
    B(B&& right) : x(std::forward<A>(right.x)){ std::cout << "B(B&&)\n"; } 

    A x; 
}; 

struct C 
{ 
    C(){} 
    C(const C& right) : x(right.x){ std::cout << "C(const C&)\n"; } 
    C(C&& right) : x(std::move(right.x)){ std::cout << "C(C&&)\n"; } 

    A x; 
}; 

struct D 
{ 
    D(){} 
    D(const D& right) : x(right.x){ std::cout << "D(const D&)\n"; } 
    D(D&& right) : x(right.x){ std::cout << "D(D&&)\n"; } 

    A x; 
}; 

int main() 
{ 
    std::cout << "--- B Test ---\n"; 
    B b1; 
    B b2(std::move(b1)); 
    std::cout << "--- C Test ---\n"; 
    C c1; 
    C c2(std::move(c1)); 
    std::cout << "--- D Test ---\n"; 
    D d1; 
    D d2(std::move(d1)); 
} 

आउटपुट:

--- B Test --- 
A(A&&) 
B(B&&) 
--- C Test --- 
A(A&&) 
C(C&&) 
--- D Test --- 
A(const A&) 
D(D&&) 

उत्तर

14

सवाल है: उन वास्तव में इस कदम निर्माता/असाइनमेंट ऑपरेटर वर्ग के लिए कर रहे हैं? या क्या वे केवल आपकी आंख के कोने से दिखते हैं?

struct X{ 
    X(X&&); // move ctor #1 

    template<class T> 
    X(T&&); // perfect forwarding ctor #2 

    X& operator=(X&&); // move assignment operator #3 

    template<class T> 
    X& operator=(T&&); // perfect forwarding ass. operator #4 
}; 

एक असली कदम ctor में (# 1) और ले जाने के असाइनमेंट ऑपरेटर (# 3), आप std::forward का उपयोग कभी नहीं होगा, क्योंकि के रूप में आप सही ढंग से आकलन किया, तो आप हमेशा पर आ जाएगा।

ध्यान दें कि std::forward कभी भी एक पूर्ण अग्रेषण टेम्पलेट (T&&) के बिना समझ में आता है। यह # 2 और # 4 के लिए बिल्कुल मामला है। यहां, आप कभी भी std::move का उपयोग नहीं करेंगे, क्योंकि आप नहीं जानते कि आपको वास्तव में एक रावल्यू (ए-ओके) या एक लवल्यू (इतना ज्यादा नहीं) मिला है या नहीं।

वास्तव में कैसे काम करता है इसके स्पष्टीकरण के लिए this answer of mine देखें।

+0

आप सही हैं, मैं गलत ctor देख रहा था। मैंने प्रश्न में कुछ उदाहरण कोड जोड़ा। – David

+0

@ डेव: 'std :: forward' का आपका उपयोग गलत है, क्योंकि 'ए' एक समर्पित टेम्पलेट पैरामीटर नहीं है। ऐसा लगता है कि यह 'std :: forward' के "rvalue" संस्करण से मेल खाता है। – Xeo

+0

मैं आपकी शब्दावली पूरी तरह से समझ नहीं पा रहा हूं, लेकिन आगे बढ़ता नहीं है (और यह हमेशा * नहीं *) एक ही चीज को हल कर सकता है जैसे std :: move ctor (rvalue to cast) में स्थानांतरित करें? साइड नोट: वीएस -2010 लगता है (गलत तरीके से?) # 1 मौजूद नहीं होने पर आपके ऑपरेटर # 2 को चालक ctor के रूप में स्वीकार करते हैं। – David

संबंधित मुद्दे