2012-01-14 20 views
6

वहाँ टेम्पलेट विशेषज्ञता के लिए एक सूक्ष्म चाल ताकि मैं basic POD करने के लिए एक विशेषज्ञता आवेदन कर सकते हैं (जब मैं बुनियादी पॉड कहते हैं कि मैं नहीं है, विशेष रूप से struct पॉड (लेकिन मुझे लगता है कि ले जाएगा) चाहते हैं) है।खाका विशेषज्ञता केवल

template<typename T> 
struct DoStuff 
{ 
    void operator()() { std::cout << "Generic\n";} 
}; 
template<> 
struct DoStuff</*SOme Magic*/> 
{ 
    void operator()() { std::cout << "POD Type\n";} 
}; 

या क्या मुझे प्रत्येक निर्मित प्रकार के लिए विशेषज्ञता लिखनी है?

template<typename T> 
struct DoStuff 
{ 
    void operator()() { std::cout << "Generic\n";} 
}; 


// Repeat the following template for each of 
// unsigned long long, unsigned long, unsigned int, unsigned short, unsigned char 
//   long long,   long,   int,   short, signed char 
// long double, double, float, bool 
// Did I forget anything? 
// 
// Is char covered by unsigned/signed char or do I need a specialization for that? 
template<> 
struct DoStuff<int> 
{ 
    void operator()() { std::cout << "POD Type\n";} 
}; 

यूनिट टेस्ट।

int main() 
{ 
    DoStuff<int>   intStuff; 
    intStuff();   // Print POD Type 


    DoStuff<std::string> strStuff; 
    strStuff();   // Print Generic 
} 
+0

ठीक है, मैं उत्सुक हूं - अगर आप "सामान" क्या करना चाहते हैं तो कार्यान्वयन पीओडी प्रकारों के लिए पहले से ही अलग नहीं है? –

+0

मैं boost :: mpl का उपयोग कर रहा हूं। वस्तुओं की तरह वर्ग के लिए मुझे एक ऐसी क्रिया को पंजीकृत करने की आवश्यकता है जो कक्षा वस्तु का उपयोग करता है (और इसके सभी सदस्यों के लिए कार्रवाई पंजीकृत करता है)। सामान्य पीओडी ऑब्जेक्ट्स के लिए मेरे पास एक बहुत ही सरल क्रिया है जो ऑब्जेक्ट पर कार्रवाई करने के लिए पंजीकृत होगी। –

उत्तर

6

आप वास्तव में केवल मौलिक प्रकार और नहीं उपयोगकर्ता परिभाषित चाहते हैं पॉड प्रकार फिर निम्न कार्य करना चाहिए:

#include <iostream> 
#include <boost/type_traits/integral_constant.hpp> 
#include <boost/type_traits/is_fundamental.hpp> 
#include <boost/type_traits/is_same.hpp> 

template<typename T> 
struct non_void_fundamental : boost::integral_constant< 
    bool, 
    boost::is_fundamental<T>::value && !boost::is_same<T, void>::value 
> 
{ }; 

template<typename T, bool Enable = non_void_fundamental<T>::value> 
struct DoStuff 
{ 
    void operator()() { std::cout << "Generic\n"; } const 
}; 

template<> 
struct DoStuff<T, true> 
{ 
    void operator()() { std::cout << "POD Type\n"; } const 
}; 

आप भी उपयोगकर्ता परिभाषित पॉड प्रकार, तो boost::is_pod<> बजाय non_void_fundamental<> (और यदि आप सी ++ 11 का उपयोग कर रहे हैं और अनुकूलन प्रयोजनों के लिए ऐसा करने के लिए, उपयोग उपयोग करना चाहते हैं इसके बजाय std::is_trivially_copyable<>)।

1

बूस्ट में boost::is_pod है। क्या आप यही खोज रहे हैं?

(मैं इसे इस्तेमाल कभी नहीं किया है, इसलिए मैं अपने आप को सटीक कोड है कि आप अपने उदाहरण के लिए आवश्यकता होती है तैयार करने के लिए कोशिश कर रहा द्वारा शर्मिंदा नहीं होगा।)

+1

सी ++ 11 में यह भी है। –

6

सी ++ 11 में, मानक पुस्तकालय में कई लक्षण जोड़े गए हैं, और अधिकांश विशेष रूप से दिलचस्प विशेषज्ञता (और विशेष रूप से बिटवाई मैनिपुलेशन) के लिए लक्षित हैं।

उच्च-स्तरीय विशेषता आप में रुचि हो सकती std::is_trivial है, लेकिन वहाँ कई अन्य लोगों के हैं:

  • std::is_trivially_default_constructible
  • std::is_trivially_copy_constructible
  • std::is_trivially_move_constructible
  • std::is_trivially_copyable (memcpy के माध्यम से कॉपी किया जा सकता)

सामान्य रूप से, मानक ने जितना संभव हो उतना बेहतर दागदार गुण प्राप्त करने की कोशिश की है, इसलिए आपको is_pod जैसी व्यापक धारणाओं पर भरोसा नहीं करना चाहिए, बल्कि इसके तरीकों से मेल खाने के लिए अपनी बाधाओं को ठीक से ट्यून करें।

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