स्पष्ट के लिए usecase क्या है (बूल)


24

C ++ 20 ने स्पष्ट (बूल) पेश किया, जो सशर्त रूप से संकलन-समय पर चयन करता है कि एक निर्माता स्पष्ट किया गया है या नहीं।

नीचे एक उदाहरण है जो मुझे यहां मिला ।

struct foo {

  // Specify non-integral types (strings, floats, etc.) require explicit construction.

  template <typename T>

  explicit(!std::is_integral_v<T>) foo(T) {}

};

foo a = 123; // OK

foo b = "123"; // ERROR: explicit constructor is not a candidate (explicit specifier evaluates to true)

foo c {"123"}; // OK

क्या कोई मुझे explicit (bool)उपयोग करने के अलावा किसी अन्य उपयोग के बारे में बता सकता है std::is_integral?


1
एक उदाहरण यह है कि tupleइस सुविधा के साथ उन जैसे सशर्त रूप से स्पष्ट निर्माणकर्ताओं को लागू करना बहुत आसान हो जाता है ।
प्रेटोरियन

1
उचित उत्तर नहीं है, लेकिन आप इसे प्रस्तुत करने वाले पेपर में प्रेरणा को भी देख सकते हैं: wg21.link/p0892
N. Shead

उदाहरण: यह (अवधारणाओं के साथ) एक सशर्त रूप से स्पष्ट रूप से स्पष्ट कॉपी कंस्ट्रक्टर को लागू करने के लिए आधार वर्गों की आवश्यक संख्या में 3 से 0. कटौती करता है
LF

जवाबों:


21

प्रेरणा खुद को कागज में देखा जा सकता है ।

कंस्ट्रक्टरों को सशर्त रूप से स्पष्ट करने की आवश्यकता है। यानी आप चाहते हैं:

pair<string, string> safe() {
    return {"meow", "purr"}; // ok
}

pair<vector<int>, vector<int>> unsafe() {
    return {11, 22}; // error
}

पूर्व ठीक है, जो निर्माणकर्ता निहित हैं। लेकिन उत्तरार्द्ध बुरा होगा, वे निर्माता हैं explicit। C ++ 17 (या अवधारणाओं के साथ C ++ 20) के साथ, इस काम को करने का एकमात्र तरीका दो निर्माणकर्ताओं को लिखना है - एक explicitऔर एक:

template <typename T1, typename T2>
struct pair {
    template <typename U1=T1, typename U2=T2,
        std::enable_if_t<
            std::is_constructible_v<T1, U1> &&
            std::is_constructible_v<T2, U2> &&
            std::is_convertible_v<U1, T1> &&
            std::is_convertible_v<U2, T2>
        , int> = 0>
    constexpr pair(U1&&, U2&& );

    template <typename U1=T1, typename U2=T2,
        std::enable_if_t<
            std::is_constructible_v<T1, U1> &&
            std::is_constructible_v<T2, U2> &&
            !(std::is_convertible_v<U1, T1> &&
              std::is_convertible_v<U2, T2>)
        , int> = 0>
    explicit constexpr pair(U1&&, U2&& );    
};  

ये लगभग पूरी तरह से डुप्लिकेट हैं - और इन निर्माणकर्ताओं की परिभाषाएं समान होंगी।

के साथ explicit(bool), आप बस एक ही कंस्ट्रक्टर लिख सकते हैं - निर्माण के सशर्त रूप से स्पष्ट भाग के साथ स्थानीयकृत explicit-specifier:

template <typename T1, typename T2>
struct pair {
    template <typename U1=T1, typename U2=T2,
        std::enable_if_t<
            std::is_constructible_v<T1, U1> &&
            std::is_constructible_v<T2, U2>
        , int> = 0>
    explicit(!std::is_convertible_v<U1, T1> ||
        !std::is_convertible_v<U2, T2>)
    constexpr pair(U1&&, U2&& );   
};

यह बेहतर तरीके से मेल खाता है, लिखने के लिए बहुत कम कोड है, और ओवरलोड रिज़ॉल्यूशन के दौरान कंपाइलर के लिए कम काम है (क्योंकि बीच में लेने के लिए कम कंस्ट्रक्टर होने चाहिए)।


1
C ++ 20 भी enable_if_tसंभावित रूप से अवधारणाओं का उपयोग करते हुए, एक हिस्से को प्रीटियर और सरल बाधा में बदलने की क्षमता प्रदान करता है । लेकिन इस सवाल के बिंदु के बगल में है।
एस्केलर

2

एक और संभावित उपयोग जो मैं देख रहा हूँ वह है

यह आम तौर पर अच्छा है, डिफ़ॉल्ट रूप से, explicitकेवल एक तर्क के साथ निर्माता के लिए है (जब तक कि रूपांतरण वांछित नहीं है)।

इसलिए

struct Foo
{
    template <typename ... Ts>
    explicit(sizeof...(Ts) == 1) Foo(Ts&&...);

    // ...
};

0

मैं explicitसशर्त रूप से आवश्यकता के लिए एक उपयोग के मामले को देख सकता था जब इनपुट एक दृश्य-प्रकार प्रकार (रॉ पॉइंटर std::string_view) हो सकता है कि कॉल के बाद नई वस्तु पर पकड़ होगी (केवल दृश्य की प्रतिलिपि बनाकर, न कि इसका क्या मतलब है, शेष पर निर्भर है देखी गई वस्तु का जीवनकाल), या यह एक मूल्य-प्रकार प्रकार हो सकता है (प्रतिलिपि का स्वामित्व लेता है, जिसमें कोई बाहरी जीवनकाल निर्भरता नहीं है)।

इस तरह की स्थिति में, कॉलर देखी गई वस्तु को जीवित रखने के लिए ज़िम्मेदार होता है (कैली एक दृश्य का मालिक होता है, न कि मूल वस्तु का), और रूपांतरण को अंतर्निहित रूप से नहीं किया जाना चाहिए, क्योंकि यह अंतर्निहित वस्तु के लिए बहुत आसान बनाता है यह देखने के उद्देश्य वस्तु। इसके विपरीत, मूल्य प्रकारों के लिए, नई वस्तु को अपनी प्रतिलिपि प्राप्त होगी, इसलिए जब कॉपी महंगी हो सकती है, तो यह अंतर्निहित गलत होने पर कोड को गलत नहीं करेगा ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.