2017-07-16 27 views
6

According to cppreference.com, std :: वेक्टर :: क़ायम करना() मजबूत अपवाद गारंटी प्रदान करता है बिना शर्त: एक अपवाद फेंक दिया हैक्या std :: vector :: emplace() वास्तव में फेंकने वाले चालक/असाइनमेंट ऑपरेटर के चेहरे में मजबूत अपवाद गारंटी प्रदान करता है?

हैं (निर्माता द्वारा जैसे), कंटेनर असंशोधित छोड़ दिया है, इस समारोह के रूप में करता है, तो कभी नहीं था कहा जाता है (मजबूत अपवाद गारंटी)।

हालांकि, यह जीसीसी 7.1.1 के साथ अभ्यास में मामला प्रतीत नहीं होता है। निम्नलिखित कार्यक्रम:

#include <iostream> 
#include <vector> 

struct ugly 
{ 
    int i; 

    ugly(int i) : i{i} { } 

    ugly(const ugly& other) = default; 

    ugly& operator=(ugly&& other) { 
    if (other.i == 3) { 
     throw other.i; 
    } 
    i = other.i; 
    return *this; 
    } 

    ugly& operator=(const ugly& other) = default; 
}; 

int main() { 
    std::vector<ugly> vec; 
    vec.reserve(6); 
    vec.emplace_back(0); 
    vec.emplace_back(1); 
    vec.emplace_back(2); 
    vec.emplace_back(4); 
    vec.emplace_back(5); 

    try { 
    vec.emplace(vec.begin() + 3, 3); 
    } catch (int i) { 
    } 

    for (const auto& u : vec) { 
    std::cout << u.i << "\n"; 
    } 

    return 0; 
} 

प्रिंट

0 
1 
2 
4 
4 
5 

वास्तव में, मैं एक कठिन समय को देखकर कैसे क़ायम करना() संभवतः मजबूत गारंटी प्रदान कर सके नकल/चलती फेंकने के लिए अनुमति दी है अगर है । बीच में जाने के लिए, हमें पहले रास्ते से तत्वों का एक गुच्छा ले जाना है, फिर इसके स्थान पर नया तत्व बनाएं। अगर इनमें से कोई भी फेंकता है, तो हमें उन सभी अन्य तत्वों को वापस ले जाना होगा जहां वे थे, लेकिन वे चाल भी फेंक सकते हैं!

तो कौन गलत है, cppreference या gcc?

+0

mispoting cppreference misquoting के लिए डाउनवोट। आपके द्वारा उद्धृत गारंटी 'emplace_back' के लिए है और (क्षमा करें, सुधार) अतिरिक्त प्रतिबंधों के बाद है। –

+1

@ArneVogel पृष्ठ [अपडेट किया गया] था (http://en.cppreference.com/mwiki/index.php?title=Template%3Acpp%2Fcontainer%2Femplace&diff=94452&oldid=75433) क्योंकि मैंने यह प्रश्न लिखा है –

उत्तर

6

C++14 मानक के मुताबिक मजबूत अपवाद गारंटी केवल तभी रखती है जब आपके द्वारा डालने वाले प्रकार में एक मजबूत अपवाद गारंटी हो।

यहाँ:

23.3.6.5 वेक्टर संशोधक [ vector.modifiers ]

iterator insert(const_iterator position, const T& x); 
iterator insert(const_iterator position, T&& x); 
iterator insert(const_iterator position, size_type n, const T& x); 
template <class InputIterator> 
iterator insert(const_iterator position, InputIterator first, InputIterator last); 
iterator insert(const_iterator position, initializer_list<T>); 
template <class... Args> void emplace_back(Args&&... args); 
template <class... Args> iterator emplace(const_iterator position, Args&&... args); 
void push_back(const T& x); 
void push_back(T&& x); 

टिप्पणी: पुनः आबंटन का कारण बनता है, तो नया आकार बड़ा होता है पुरानी क्षमता की तुलना में। यदि कोई पुनर्वितरण नहीं होता है, तो सम्मिलन बिंदु से पहले सभी पुनरावृत्तियों और संदर्भ मान्य रहते हैं। यदि कोई अपवाद कॉपी कन्स्ट्रक्टर के अलावा, कन्स्ट्रक्टर, असाइनमेंट ऑपरेटर को स्थानांतरित करता है, या टी के असाइनमेंट ऑपरेटर को ले जाता है या किसी इनपुट इनपुट ऑपरेटर पर कोई प्रभाव नहीं पड़ता है। यदि अंत में एक तत्व डालने के दौरान एक अपवाद फेंक दिया जाता है और टी प्रतिलिपि है या is_nothrow_move_constructible :: मान सत्य है, तो कोई प्रभाव नहीं है। अन्यथा, यदि एक गैर-प्रतिलिपि बनाने योग्य टी के चालक कन्स्ट्रक्टर द्वारा अपवाद फेंक दिया जाता है, तो प्रभाव निर्दिष्ट नहीं होते हैं।

तो ऐसा लगता है कि cppreference.com गलत है।

+0

इनमें से कौन सी टिप्पणियां क्या आपको लगता है कि लागू होता है? –

+1

@TavianBarnes "के अलावा ... टी के असाइनमेंट ऑपरेटर ऑपरेटर"। आपका उदाहरण इसके * चाल असाइनमेंट ऑपरेटर * में अपवाद फेंकता है। – Galik

+0

ठीक है, ताकि वाक्य लागू न हो। लेकिन न तो दूसरों में से कोई भी, इसलिए मुझे लगता है कि इस मामले में emplace() के व्यवहार पर कोई बाधा नहीं डालती है। धन्यवाद! –

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