c++ - शून्य का क्या अर्थ है, या यह इस मामले में टी को कैसे प्रभावित करता है?




c++11 templates (2)

इसलिए मैं C ++ में मेरे एक दोस्त के साथ कुछ काम कर रहा था, और हम इस दस्तावेज में आए।

//(until C++14)
template<class T>
struct less;
//(since C++14)
template<class T = void>
struct less;

अब मुझे पता है कि यह class T = int और डबल और फ्लोट और अन्य प्रकार की कक्षाओं के लिए समान है। लेकिन जिस हिस्से को लेकर मैं बहुत उलझन में हूं, वह यह है कि इस मामले में शून्य कैसे काम करता है? और शून्य का उपयोग करके सीमाएं क्या हैं?

मैं यह इसलिए पूछ रहा हूं क्योंकि C ++ डॉक्यूमेंटेशन बहुत मददगार है और न ही मैं इसे कहीं और बताता हूं जो इसे समझाए।


आपके कोड स्निपेट को देखते हुए मैं मान सकता हूं कि आप मानक पुस्तकालय से फ़ंक्शन ऑब्जेक्ट का उल्लेख कर रहे हैं, अर्थात, en.cppreference.com/w/cpp/utility/functional/less

सामान्य तौर पर, डिक्लेरेशन template<class T = void> अन्य प्रकारों (जैसे int , उदाहरण के लिए) के लिए बिल्कुल काम करता है। संक्षेप में, जब टाइप टेम्प्लेट के तर्क को निर्दिष्ट किए बिना उस वर्ग की किसी वस्तु को त्वरित किया जाता है, तो void काट void जाएगा।

std::less<int> li;   // std::less<T = int>;
std::less<void> lv;  // std::less<T = void>;
std::less<> lv2;     // std::less<T = void>; exactly as one row above.

इस विशेष मामले में, जब T = void तो std::less एक टेम्पलेट विशेषज्ञता प्रदान करता है।

ऑब्जेक्ट std::less<void> एक आसान विशेषज्ञता है जो operator() साथ "स्वचालित रूप से" तुलना करने के लिए प्रकारों को कम करने की अनुमति देता है। इसके अलावा, इसकी जरूरत तब पड़ती है जब आप दो अलग-अलग प्रकारों की तुलना करना चाहते हैं, जो अनुमानित रूप से परिवर्तनीय नहीं हैं।

व्यावहारिक उदाहरण:

हमें मान लें कि आपके पास दो वस्तुएं हैं जिनकी आप तुलना कर सकते हैं।

/*Let us assume you have two objects you can compare*/
struct Foo;
struct Bar;

struct Foo {
  bool operator<(const Bar&) const;  
};

struct Bar {
  bool operator<(const Foo&) const;
};

Foo और Bar की एक दूसरे से तुलना की जा सकती है, लेकिन वे अलग-अलग प्रकार के होते हैं।

आप किस प्रकार के फंक्टर के लिए निर्दिष्ट करेंगे std::less इस मामले में std::less ?

void WrongCode() {
  std::less<Foo> l;
  l(Foo{}, Bar{});  // error
}

यदि हम std::less<Foo> उपयोग करते हैं, तो फ़नकार केवल Foo प्रकार की वस्तुओं को स्वीकार करेगा। (बेशक, वही std::less<Bar> )।

इसलिए, मानक इस मामले को कवर करने के लिए यह आसान विशेषज्ञता प्रदान करता है।

void GoodCode() {
  std::less<> l;
  l(Foo{}, Bar{});  // this compile
}

GoodCode संकलित करेगा क्योंकि operator() के प्रकार operator() का std::less<void> स्वचालित रूप से काट लिया जाता है (और वे अलग भी हो सकते हैं)।


सामान्य तौर पर इसका मतलब यह है कि आप किसी विशेष मामले को संसाधित करने के लिए टाइप शून्य के लिए एक वर्ग का विशेषज्ञ होने जा रहे हैं।

यहाँ एक प्रदर्शन कार्यक्रम है।

#include <iostream>

template <class T = void>
struct A
{
    void operator ()( const T & t ) const 
    { 
        std::cout << "primary template\n"; 
        std::cout << 2 * t << '\n';
    }
};

template <>
struct A<>
{
    template <typename U>
    void operator ()( const U &u ) const 
    { 
        std::cout << "specialization for void\n";
        std::cout << 10 * u << '\n';
    }
};

int main()
{
    A<int>()( 1 );
    A<>()( 1 );
}

इसका आउटपुट है

primary template
2
specialization for void
10




templates