क्या std :: वेक्टर रेंज कंस्ट्रक्टर स्पष्ट रूपांतरण कर सकता है?


14

निम्नलिखित कार्यक्रम अच्छी तरह से गठित है?

#include <vector>
struct A {
    explicit A(int) {}
};
int main() {
    std::vector<int> vi = {1, 2, 3, 4, 5};
    std::vector<A> va(vi.begin(), vi.end());
}

C ++ 17 के अनुसार [क्रम ।reqmts], के लिए आवश्यकता

X u(i, j);

Xएक अनुक्रम कंटेनर कहां है:

Tहोगा EmplaceConstructibleमें Xसे *i

हालाँकि, पूर्ववर्ती पैराग्राफ में यह कहा गया है कि:

iऔर jइनपुट पुनरावृत्तियों आवश्यकताओं को पूरा करने वाले पुनरावृत्तियों को निरूपित करते हैं और तत्वों को संदर्भित करते हैं, जो स्पष्ट रूप से परिवर्तनीय हैं value_type,

इस प्रकार यह मुझे लगता है कि दोनों आवश्यकताओं को पूरा करने की आवश्यकता होगी: श्रेणी के मूल्य प्रकार को कंटेनर के मूल्य प्रकार के लिए परिवर्तनीय होना चाहिए , और EmplaceConstructible संतुष्ट होना चाहिए (जिसका अर्थ है कि आवंटनकर्ता आवश्यक प्रारंभ करने में सक्षम होना चाहिए) । चूंकि intअंतर्निहित रूप से परिवर्तनीय नहीं है A, इसलिए इस कार्यक्रम को बीमार होना चाहिए।

हालांकि, आश्चर्यजनक रूप से, यह जीसीसी के तहत संकलन लगता है


(रिकॉर्ड के लिए, यह केवल gcc नहीं है: godbolt.org/z/ULeRDw )
मैक्स

इस मामले में कोई अंतर्निहित रूपांतरण की आवश्यकता नहीं है, क्योंकि स्पष्ट निर्माता पहले से ही प्रकार फिट करता है। मुझे लगता है कि विवरण भ्रामक है, लेकिन स्पष्ट निर्माण हमेशा बेहतर होता है फिर निर्माण से पहले निहित रूपांतरण।
JHBonarius

जवाबों:


2

यह केवल अनुक्रम कंटेनरों के लिए एक आवश्यकता है जो पुनरावृत्तियों से निर्माण का समर्थन करते हैं जो निहित परिवर्तनीयता के मानदंडों को पूरा करते हैं।

यह अपने आप में अनुक्रम कंटेनरों को उस निर्माणकर्ताओं से उस निर्माण का समर्थन करने से नहीं रोकता है जो उस मानदंड को संतुष्ट नहीं करते हैं जहां तक ​​मैं 1 बता सकता हूं । उस बारे में स्पष्ट नियम है:

यदि कन्स्ट्रक्टर ... को एक प्रकार के इनपुटइंटरेटर के साथ कहा जाता है , जो इनपुट इटरेटर के रूप में अर्हता प्राप्त नहीं करता है , तो कंस्ट्रक्टर ओवरलोड रिज़ॉल्यूशन में भाग नहीं लेगा।

यह स्पष्ट नहीं है कि "इनपुट इटरेटर के रूप में अर्हता प्राप्त" का अर्थ क्या है। क्या यह Cpp17InputIterator को व्यक्त करने का अनौपचारिक तरीका है, या क्या यह i और j की आवश्यकताओं को संदर्भित करने का प्रयास करता है? मुझे नहीं पता। इसकी अनुमति है या नहीं, इसका पता लगाने के लिए मानक की सख्त आवश्यकता नहीं है:

[Container.requirements.general]

कुछ कंटेनर सदस्य फ़ंक्शंस और डिडक्शन गाइड का व्यवहार इस बात पर निर्भर करता है कि प्रकार इनपुट इनपुटर्स या एलोकेटर के रूप में योग्य हैं या नहीं। एक कार्यान्वयन के लिए यह निर्धारित करता है कि एक प्रकार एक इनपुट पुनरावृत्ति नहीं हो सकता है, अनिर्दिष्ट है, सिवाय इसके कि एक न्यूनतम अभिन्न प्रकार इनपुट पुनरावृत्तियों के रूप में अर्हता प्राप्त नहीं करेगा। ...

इस व्याख्या के साथ कि कोई भी Cpp17InputIterator "एक इनपुट पुनरावृत्त के रूप में अर्हता प्राप्त करता है", उदाहरण कार्यक्रम को बीमार होने की आवश्यकता नहीं होगी। लेकिन यह अच्छी तरह से बनने की गारंटी नहीं है।

1 ऐसे मामले में, इसे लागू करने पर चेतावनी देने के लिए इसे लागू करने का एक गुण माना जा सकता है। दूसरी ओर, निहित रूपांतरणों के लिए इस सीमा को दोष माना जा सकता है ।


पुनश्च यह Clang (libc ++ के साथ) और Msvc के साथ-साथ चेतावनी के बिना संकलित करता है।

PPS यह शब्द C ++ 11 में जोड़ा गया है (जो स्वाभाविक है, जैसा कि तब स्पष्ट निर्माणकर्ता भी पेश किए गए थे)।


1
वास्तव में इस बात पर निर्भर करता है कि "इनपुट इटरेटर के रूप में योग्य नहीं है" का अर्थ क्या है। विपरीत इसके बाद के संस्करण , यह वास्तव में नहीं कहा गया है Cpp17InputIterator, तो यह है कि क्या मेरे लिए स्पष्ट नहीं कर रहा है "और तत्वों परोक्ष के लिए परिवर्तनीय का उल्लेख value_type" "इनपुट इटरेटर" में शामिल है। यदि यह है, तो निर्माणकर्ता को अधिभार संकल्प में भाग नहीं लेना चाहिए और कार्यक्रम को बीमार होना चाहिए।
मैक्स लैंगहॉफ़

1
इसलिए, प्रत्येक मानक पुस्तकालय वर्ग को नैदानिक ​​जारी किए बिना अतिरिक्त निर्माणकर्ताओं को अनुमति दी जाती है जब उन अतिरिक्त निर्माणकर्ताओं का उपयोग किया जाता है? यह सहज रूप से मुझे गलत लगता है ...
ब्रायन

@ ब्रायन मुझे यकीन नहीं है कि अगर इसके "अतिरिक्त निर्माता" हैं, लेकिन शायद अधिक "निर्माणकर्ताओं के विशिष्ट कार्यान्वयन जो अधिक कमरे की अनुमति देते हैं"। हर इनपुट की जाँच करने से महत्वपूर्ण प्रदर्शन प्रभाव पड़ सकता है, इसलिए मुझे नहीं पता कि क्या वह रास्ता होगा ...
JHBonarius

@ ब्रायन यह निश्चित रूप से एक बुरा विचार होगा भले ही स्पष्ट रूप से अस्वीकृत न हो। इस मामले में हम केवल इस बात पर विचार कर रहे हैं कि क्या एक आवश्यक निर्माणकर्ता को प्रकार के पुनरावृत्तियों का समर्थन करने की अनुमति दी गई है जिसे समर्थन करने की आवश्यकता नहीं है। इस मामले में मैक्स द्वारा इंगित की गई "आवश्यकता नहीं होगी" के रूप में स्पष्ट है, जो निश्चित रूप से इसे अस्वीकार कर देगा। लेकिन यह वास्तव में स्पष्ट नहीं है कि "इनपुट इटरेटर के रूप में अर्हता प्राप्त" का अर्थ क्या है। क्या यह व्यक्त करने का अनौपचारिक तरीका है Cpp17InputIterator, या क्या यह आवश्यकताओं के संदर्भ में iऔर j? मुझे नहीं पता।
एरोरिका

2
1) C ++ में हम मानक कम सेट करते हैं। । 2) कंस्ट्रक्टर गैर-आभासी सदस्य कार्य हैं । 3) LWG 3297 देखें ; हालाँकि मुझे इस बात पर विशेष रूप से विश्वास नहीं है कि हमें निहित रूपांतरण आवश्यकता को हटा देना चाहिए।
टीसी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.