हटाए गए फ़ंक्शन का निहितार्थ है
(मौजूदा उत्तरों के लिए परिशिष्ट)
... और हटाए गए फ़ंक्शन फ़ंक्शन की पहली घोषणा होगी (फ़ंक्शन टेम्प्लेट की स्पष्ट विशेषज्ञता को हटाने के अलावा - विलोपन विशेषज्ञता के पहले घोषणा पर होना चाहिए), जिसका अर्थ है कि आप फ़ंक्शन की घोषणा नहीं कर सकते हैं और बाद में इसे हटा सकते हैं, कहते हैं, अनुवाद इकाई में इसकी परिभाषा स्थानीय है।
उद्धृत करना [dcl.fct.def.delete] / 4 :
हटाए गए फ़ंक्शन का निहितार्थ है। ( नोट: एक परिभाषा नियम ( [basic.def.odr] ) हटाए गए परिभाषाओं पर लागू होता है। - अंतिम नोट ] किसी फ़ंक्शन की हटाए गए परिभाषा फ़ंक्शन फ़ंक्शन की स्पष्ट विशेषज्ञता के लिए फ़ंक्शन की पहली घोषणा होगी या। उस विशेषज्ञता की पहली घोषणा। [उदाहरण:
struct sometype {
sometype();
};
sometype::sometype() = delete; // ill-formed; not first declaration
- अंतिम उदाहरण )
हटाए गए परिभाषा के साथ एक प्राथमिक फ़ंक्शन टेम्पलेट विशिष्ट हो सकता है
अंगूठे का एक सामान्य नियम है, विशेष प्रकार के टेम्प्लेट से बचने के लिए, क्योंकि विशेषज्ञ अतिभार के पहले चरण में भाग नहीं लेते हैं, ऐसे कुछ संदर्भ हैं जहां यह उपयोगी हो सकता है। जब एक गैर-अतिभारित का उपयोग कर सभी प्रकार के मिलान के लिए बिना किसी परिभाषा के प्राथमिक फ़ंक्शन टेम्पलेट जो कि एक अन्यथा मिलान-दर-रूपांतरण अधिभार में परिवर्तित नहीं होता है; यानी, गैर-परिभाषित, गैर-अतिभारित प्राथमिक फ़ंक्शन टेम्पलेट के स्पष्ट विशेषज्ञता में केवल सटीक प्रकार के मैचों को लागू करके कई निहितार्थ-रूपांतरण मैचों को हटाने के लिए।
C ++ 11 की डिलीटेड फंक्शन कॉन्सेप्ट से पहले, कोई भी प्राथमिक फ़ंक्शन टेम्प्लेट की परिभाषा को छोड़ कर ऐसा कर सकता था, लेकिन इसने अस्पष्ट अपरिष्कृत संदर्भ त्रुटियां दीं, जो प्राथमिक फ़ंक्शन टेम्प्लेट के लेखक से जानबूझकर कोई अर्थपूर्ण इरादे नहीं देती थीं (जानबूझकर छोड़ा गया ?)। यदि हम इसके बजाय प्राथमिक फ़ंक्शन टेम्पलेट को स्पष्ट रूप से हटाते हैं, तो कोई उपयुक्त स्पष्ट विशेषज्ञता नहीं मिलने की स्थिति में त्रुटि संदेश बहुत अच्छे हो जाते हैं, और यह भी दर्शाता है कि प्राथमिक फ़ंक्शन टेम्पलेट की परिभाषा का चूक / विलोपन जानबूझकर किया गया था।
#include <iostream>
#include <string>
template< typename T >
void use_only_explicit_specializations(T t);
template<>
void use_only_explicit_specializations<int>(int t) {
std::cout << "int: " << t;
}
int main()
{
const int num = 42;
const std::string str = "foo";
use_only_explicit_specializations(num); // int: 42
//use_only_explicit_specializations(str); // undefined reference to `void use_only_explicit_specializations< ...
}
हालाँकि, उपर्युक्त प्राथमिक फ़ंक्शन टेम्प्लेट के लिए एक परिभाषा को छोड़ देने के बजाय, अस्पष्ट अस्पष्ट संदर्भ त्रुटि उत्पन्न होने पर जब कोई स्पष्ट विशेषज्ञता मेल नहीं खाती है, तो प्राथमिक टेम्पलेट परिभाषा को हटाया जा सकता है:
#include <iostream>
#include <string>
template< typename T >
void use_only_explicit_specializations(T t) = delete;
template<>
void use_only_explicit_specializations<int>(int t) {
std::cout << "int: " << t;
}
int main()
{
const int num = 42;
const std::string str = "foo";
use_only_explicit_specializations(num); // int: 42
use_only_explicit_specializations(str);
/* error: call to deleted function 'use_only_explicit_specializations'
note: candidate function [with T = std::__1::basic_string<char>] has
been explicitly deleted
void use_only_explicit_specializations(T t) = delete; */
}
अधिक पठनीय त्रुटि संदेश प्राप्त करना, जहां विलोपन का इरादा भी स्पष्ट रूप से दिखाई देता है (जहां एक अपरिभाषित संदर्भ त्रुटि डेवलपर को यह एक गलत सोच समझ सकती है)।
हम इस तकनीक का उपयोग क्यों करना चाहते हैं? फिर से, स्पष्ट विशेषज्ञताओं के लिए उपयोगी हो सकता है परोक्ष अंतर्निहित रूपांतरण को हटा दें।
#include <cstdint>
#include <iostream>
void warning_at_best(int8_t num) {
std::cout << "I better use -Werror and -pedantic... " << +num << "\n";
}
template< typename T >
void only_for_signed(T t) = delete;
template<>
void only_for_signed<int8_t>(int8_t t) {
std::cout << "UB safe! 1 byte, " << +t << "\n";
}
template<>
void only_for_signed<int16_t>(int16_t t) {
std::cout << "UB safe! 2 bytes, " << +t << "\n";
}
int main()
{
const int8_t a = 42;
const uint8_t b = 255U;
const int16_t c = 255;
const float d = 200.F;
warning_at_best(a); // 42
warning_at_best(b); // implementation-defined behaviour, no diagnostic required
warning_at_best(c); // narrowing, -Wconstant-conversion warning
warning_at_best(d); // undefined behaviour!
only_for_signed(a);
only_for_signed(c);
//only_for_signed(b);
/* error: call to deleted function 'only_for_signed'
note: candidate function [with T = unsigned char]
has been explicitly deleted
void only_for_signed(T t) = delete; */
//only_for_signed(d);
/* error: call to deleted function 'only_for_signed'
note: candidate function [with T = float]
has been explicitly deleted
void only_for_signed(T t) = delete; */
}