2013-03-04 7 views
8

मैं सी ++ (11 नहीं) का उपयोग कर रहा हूं और कुछ पुस्तकालयों का उपयोग कर रहा हूं जिनमें पूर्णांक डेटा प्रकारों के लिए अलग-अलग टाइपिफ़ी हैं। क्या कोई तरीका है कि मैं कह सकता हूं कि दो टाइपिफ एक ही प्रकार के हैं? मैं अपने आप निम्नलिखित समाधान के साथ आया हूँ .. क्या यह सुरक्षित है? धन्यवादटाइपिफ़ की तुलना करें

template<typename T> 
struct TypeTest 
{ 
    static void Compare(const TypeTest& other) {} 
}; 

typedef unsigned long long UINT64; 
typedef unsigned long long UINT_64; 
typedef unsigned int UINT_32; 

int main() 
{ 
    TypeTest<UINT64>::Compare(TypeTest<UINT64>()); // pass 
    TypeTest<UINT64>::Compare(TypeTest<UINT_64>()); // pass 
    TypeTest<UINT64>::Compare(TypeTest<UINT_32>()); // fail 
} 
+2

cppreference 'std :: is_same' का नमूना कार्यान्वयन है: http://en.cppreference.com/w/cpp/types/is_same – us2012

उत्तर

24

सी ++ 11 में, आप std::is_same<T,U>::value का उपयोग कर सकते हैं।

जब से तुम सी ++ 11 की जरूरत नहीं है, आप के रूप में इस कार्यक्षमता खुद को लागू कर सकते हैं:

template<typename T, typename U> 
struct is_same 
{ 
    static const bool value = false; 
}; 

template<typename T> 
struct is_same<T,T> //specialization 
{ 
    static const bool value = true; 
}; 

हो गया!

इसी तरह आप लागू कर सकते हैं static_assert के रूप में:

template<bool> struct static_assert; 
template<> struct static_assert<true> {}; //specialization 

अब आप उन्हें के रूप में उपयोग कर सकते हैं:

static_assert<is_same<UINT64,UINT64>::value>(); //pass 
static_assert<is_same<UINT64,UINT32>::value>(); //fail 

या आप के रूप में एक मैक्रो में इस लपेट सकता है:

#define STATIC_ASSERT(x) { static_assert<x> static_assert_failed; (void) static_assert_failed; } 

फिर इस प्रकार उपयोग करें:

STATIC_ASSERT(is_same<UINT64,UINT64>::value); //pass 
STATIC_ASSERT(is_same<UINT64,UINT32>::value); //pass 

आप मैक्रो का उपयोग करते हैं, तो आप निम्न स्ट्रिंग संकलक उत्पन्न संदेश में देखना होगा अगर ज़ोर विफल रहता है:

static_assert_failed 

जो उपयोगी है। त्रुटि संदेश में अन्य जानकारी के साथ, आप यह समझने में सक्षम होंगे कि यह क्यों विफल हुआ।

उम्मीद है कि मदद करता है।


1. ध्यान दें कि सी ++ 11 में, static_assert एक ऑपरेटर (जो संकलन समय पर चल रही है), नहीं एक वर्ग टेम्पलेट है। उपरोक्त कोड में, static_assert एक क्लास टेम्पलेट है।

+0

हाय। मैं VS2008 पर अपने समाधान कोशिश कर रहा हूँ, लेकिन लाइन टेम्पलेट static_assert त्रुटियों देता है: त्रुटि C4430: लापता प्रकार निर्दिष्टकर्ता - ग्रहण इंट। नोट: सी ++ डिफ़ॉल्ट-int त्रुटि C2998 का ​​समर्थन नहीं करता है: 'int static_assert': टेम्पलेट परिभाषा –

+0

@NeilKirk नहीं हो सकता है: ओह। मैं 'static_assert' की परिभाषा में 'संरचना' भूल गया। इसे अभी तय करें। – Nawaz

+0

कहें कि UINT32 को बिना हस्ताक्षर किए गए int या हस्ताक्षरित लंबे int को परिभाषित किया जा सकता है। क्या ये आपके कोड में इसकी तुलना करेंगे? धन्यवाद। –

3

चूंकि आपके पास C++ 11 नहीं है, तो बूस्ट का उपयोग करें।

BOOST_STATIC_ASSERT(boost::is_same<T, U>::value); 

आप BOOST_STATIC_ASSERT की बजाय आपके ज़ोर समारोह के कुछ प्रकार लिख सकते हैं।

+0

जबकि आप पहले ही बूस्ट का उपयोग कर रहे हैं, रन-टाइम' जोर दें 'संकलन-समय' BOOST_STATIC_ASSERT' के साथ। –

+0

@ माइकल वाइल्ड, जोर से सी जोर नहीं है, यह आपके किसी तरह का जोर कार्य है। – ForEveR

+2

यह अप्रासंगिक है। महत्वपूर्ण बात यह है कि ओपी शायद 'assert' को संकलित समय के दौरान पास/असफल करना चाहता है, रन-टाइम पर नहीं। –

1

std :: type_info आपकी मदद कर सकता है।

+0

सी ++ 11 है ... –

+0

@ माइकल वाइल्ड: [इस] के अनुसार (http://www.cplusplus.com/reference/typeinfo/type_info/) पृष्ठ यह C++ 11 निर्दिष्ट नहीं है। क्या मैं सही हू ? – Kamouth

+0

क्षमा करें, मैंने इसे '' शीर्षलेख से उलझन में डाल दिया। –

संबंधित मुद्दे