C++
प्रकार लक्षण
खोज…
टिप्पणियों
प्रकार लक्षण समय पर विभिन्न प्रकार के गुणों की तुलना और परीक्षण करने के लिए उपयोग किए जाने वाले अस्थायी निर्माण हैं। उनका उपयोग संकलित समय पर सशर्त तर्क प्रदान करने के लिए किया जा सकता है जो आपके कोड की कार्यक्षमता को विशिष्ट तरीके से सीमित या विस्तारित कर सकता है। प्रकार गुण लाइब्रेरी को c++11
मानक के साथ लाया गया था जो एक नंबर अलग कार्यशीलता प्रदान करता है। यह भी संभव है कि आप अपनी खुद की टाइप ट्रेस तुलना टेम्प्लेट बनाएं।
मानक प्रकार लक्षण
type_traits
हेडर में संकलन-समय पर प्रकारों के गुणों को बदलने और जांचने के लिए टेम्प्लेट क्लासेस और type_traits
एक सेट होता है।
ये लक्षण आमतौर पर उपयोगकर्ता त्रुटियों की जांच करने, सामान्य प्रोग्रामिंग का समर्थन करने और अनुकूलन के लिए अनुमति देने के लिए खाके में उपयोग किए जाते हैं।
अधिकांश प्रकार के लक्षण यह जांचने के लिए उपयोग किए जाते हैं कि क्या कोई प्रकार कुछ मानदंडों को पूरा करता है। इनका निम्न रूप है:
template <class T> struct is_foo;
टेम्पलेट वर्ग एक प्रकार है जो कुछ मानदंडों को पूरा करता साथ instantiated है, तो foo
, तो is_foo<T>
inherits से std::integral_constant<bool,true>
(उर्फ std::true_type
), अन्यथा यह विरासत में से std::integral_constant<bool,false>
(aka std::false_type
)। यह लक्षण निम्नलिखित सदस्यों को देता है:
स्थिरांक
static constexpr bool value
true
अगर T
मापदंड को पूरा करता है foo
, false
अन्यथा
कार्य
operator bool
value
लौटाता है
bool operator()
value
लौटाता है
प्रकार
नाम | परिभाषा |
---|---|
value_type | bool |
type | std::integral_constant<bool,value> |
इसके बाद गुण का उपयोग static_assert
या std::enable_if
जैसे निर्माणों में किया जा सकता है। std::is_pointer
: के साथ एक उदाहरण
template <typename T>
void i_require_a_pointer (T t) {
static_assert(std::is_pointer<T>::value, "T must be a pointer type");
}
//Overload for when T is not a pointer type
template <typename T>
typename std::enable_if<!std::is_pointer<T>::value>::type
does_something_special_with_pointer (T t) {
//Do something boring
}
//Overload for when T is a pointer type
template <typename T>
typename std::enable_if<std::is_pointer<T>::value>::type
does_something_special_with_pointer (T t) {
//Do something special
}
विभिन्न लक्षण भी हैं जो प्रकारों को बदलते हैं, जैसे कि std::add_pointer
और std::underlying_type
std::add_pointer
। ये लक्षण आम तौर पर एकल type
सदस्य प्रकार को उजागर करते हैं जिसमें परिवर्तित प्रकार होता है। उदाहरण के लिए, std::add_pointer<int>::type
int*
।
Std :: is_same के साथ संबंध टाइप करें
std::is_same<T, T>
प्रकार के संबंध का उपयोग दो प्रकारों की तुलना करने के लिए किया जाता है। यह बूलियन के रूप में मूल्यांकन करेगा, सच है यदि प्रकार समान और झूठे हैं यदि अन्यथा।
जैसे
// Prints true on most x86 and x86_64 compilers.
std::cout << std::is_same<int, int32_t>::value << "\n";
// Prints false on all compilers.
std::cout << std::is_same<float, int>::value << "\n";
// Prints false on all compilers.
std::cout << std::is_same<unsigned int, int>::value << "\n";
std::is_same
टाइप रिलेशन भी टाइपराइफ्स की परवाह किए बिना काम करेगा। यह वास्तव में पहले उदाहरण में दिखाया गया है जब int == int32_t
तुलना की int == int32_t
लेकिन यह पूरी तरह से स्पष्ट नहीं है।
जैसे
// Prints true on all compilers.
typedef int MyType
std::cout << std::is_same<int, MyType>::value << "\n";
std::is_same
का प्रयोग std::is_same
को चेतावनी देने के लिए जब अनुचित तरीके से टेम्प्लेटेड क्लास या फ़ंक्शन का उपयोग कर रहा हो।
जब स्थिर std::is_same
के साथ संयुक्त std::is_same
टेम्पलेट टेम्प्लेटेड कक्षाओं और कार्यों के समुचित उपयोग को लागू करने में महत्वपूर्ण उपकरण हो सकता है।
उदाहरण ए फ़ंक्शन जो केवल एक int
से इनपुट और दो संरचना का विकल्प देता है।
#include <type_traits>
struct foo {
int member;
// Other variables
};
struct bar {
char member;
};
template<typename T>
int AddStructMember(T var1, int var2) {
// If type T != foo || T != bar then show error message.
static_assert(std::is_same<T, foo>::value ||
std::is_same<T, bar>::value,
"This function does not support the specified type.");
return var1.member + var2;
}
मौलिक प्रकार के लक्षण
विभिन्न प्रकार के कई लक्षण हैं जो सामान्य प्रकारों की तुलना करते हैं।
अभिन्न है:
सभी पूर्णांक प्रकार int
, char
, long
, unsigned int
आदि के लिए सही है।
std::cout << std::is_integral<int>::value << "\n"; // Prints true.
std::cout << std::is_integral<char>::value << "\n"; // Prints true.
std::cout << std::is_integral<float>::value << "\n"; // Prints false.
फ़्लोटिंग पॉइंट है:
सभी फ़्लोटिंग पॉइंट प्रकारों के लिए सही के रूप में मूल्यांकन करता है। float
, double
, long double
आदि।
std::cout << std::is_floating_point<float>::value << "\n"; // Prints true.
std::cout << std::is_floating_point<double>::value << "\n"; // Prints true.
std::cout << std::is_floating_point<char>::value << "\n"; // Prints false.
ईनम है:
enum class
सहित सभी प्रगणित प्रकारों के लिए सही के रूप में मूल्यांकन करता है।
enum fruit {apple, pair, banana};
enum class vegetable {carrot, spinach, leek};
std::cout << std::is_enum<fruit>::value << "\n"; // Prints true.
std::cout << std::is_enum<vegetable>::value << "\n"; // Prints true.
std::cout << std::is_enum<int>::value << "\n"; // Prints false.
सूचक है:
सभी बिंदुओं के लिए सच के रूप में मूल्यांकन करता है।
std::cout << std::is_pointer<int *>::value << "\n"; // Prints true.
typedef int* MyPTR;
std::cout << std::is_pointer<MyPTR>::value << "\n"; // Prints true.
std::cout << std::is_pointer<int>::value << "\n"; // Prints false.
कक्षा है:
सभी वर्गों और संरचना के लिए सच के रूप में मूल्यांकन करता है, enum class
के अपवाद के साथ।
struct FOO {int x, y;};
class BAR {
public:
int x, y;
};
enum class fruit {apple, pair, banana};
std::cout << std::is_class<FOO>::value << "\n"; // Prints true.
std::cout << std::is_class<BAR>::value << "\n"; // Prints true.
std::cout << std::is_class<fruit>::value << "\n"; // Prints false.
std::cout << std::is_class<int>::value << "\n"; // Prints false.
प्रकार के गुण
प्रकार गुण उन संशोधक की तुलना करते हैं जिन्हें विभिन्न चर पर रखा जा सकता है। इन प्रकार के लक्षणों की उपयोगिता हमेशा स्पष्ट नहीं होती है।
नोट: नीचे दिया गया उदाहरण केवल गैर-अनुकूलन वाले संकलक में सुधार की पेशकश करेगा। यह जटिल उदाहरण के बजाय अवधारणा का सरल प्रमाण है।
उदाहरण के लिए फास्ट को चार से विभाजित करें।
template<typename T>
inline T FastDivideByFour(cont T &var) {
// Will give an error if the inputted type is not an unsigned integral type.
static_assert(std::is_unsigned<T>::value && std::is_integral<T>::value,
"This function is only designed for unsigned integral types.");
return (var >> 2);
}
लगातार है:
यह सही है जब प्रकार स्थिर होगा।
std::cout << std::is_const<const int>::value << "\n"; // Prints true.
std::cout << std::is_const<int>::value << "\n"; // Prints false.
अस्थिर है:
यह तब सत्य होगा जब प्रकार अस्थिर होगा।
std::cout << std::is_volatile<static volatile int>::value << "\n"; // Prints true.
std::cout << std::is_const<const int>::value << "\n"; // Prints false.
हस्ताक्षरित है:
यह सभी हस्ताक्षरित प्रकारों के लिए सही के रूप में मूल्यांकन करेगा।
std::cout << std::is_signed<int>::value << "\n"; // Prints true.
std::cout << std::is_signed<float>::value << "\n"; // Prints true.
std::cout << std::is_signed<unsigned int>::value << "\n"; // Prints false.
std::cout << std::is_signed<uint8_t>::value << "\n"; // Prints false.
निरुपित है:
सभी अहस्ताक्षरित प्रकारों के लिए सही के रूप में मूल्यांकन करेगा।
std::cout << std::is_unsigned<unsigned int>::value << "\n"; // Prints true.
std::cout << std::is_signed<uint8_t>::value << "\n"; // Prints true.
std::cout << std::is_unsigned<int>::value << "\n"; // Prints false.
std::cout << std::is_signed<float>::value << "\n"; // Prints false.