2016-12-01 7 views
17

मैं typedef निष्पादित करना चाहता हूं, अगर केवल एक संकलन-समय की स्थिति पूरी हो जाती है। यदि स्थिति पूरी नहीं हुई है, तो typedef बिल्कुल नहीं किया जाएगा।"if (condition) typedef" करने के लिए कोई तरीका है ... "

क्या यह सी ++ 11 में संभव है?

उदाहरण:

class A { 
    std::conditional_typedef<true,int,myType1>; // Performs "typedef int myType1". 
    std::conditional_typedef<false,int,myType2>; // Does nothing at all. 
}; 

मैं इस काल्पनिक std::conditional_typedef रहा हूँ।

+3

क्या आप सैद्धांतिक 'if (...) typedef ...;' के साथ कुछ उदाहरण कोड प्रदान कर सकते हैं? विशेष रूप से, टाइप किए गए कोड के साथ क्या होना चाहिए जो typedef का उपयोग करता है यदि टाइपपीफ "निष्पादित" नहीं है? – Quentin

+11

[std :: enable_if] (http://en.cppreference.com/w/cpp/types/enable_if) – Danh

+1

हालत विशेषज्ञता के आधार पर पर्याप्त हो सकता है ... –

उत्तर

19

एक और तरीका है std करने के लिए एक आधार वर्ग

// foo is a light struct (only a typedef or not at all) that can be 
// developed in two versions 

template <bool> 
struct foo; 

template <> 
struct foo<true> 
{ typedef int myType1; }; // or using myType1 = int; 

template <> 
struct foo<false> 
{ }; 

template <bool B> 
struct bar : public foo<B> // B can be a type_traits value derived 
          // from template arguments for bar 
{ 
    // potential complex struct or class, developed only one time 
}; 


int main() 
{ 
    bar<true>::myType1 mt1 { 1 }; 
    // bar<false>::myType1 mt2 { 1 }; error: ‘myType1’ is not a member of ‘bar<false>’ 
} 
+0

विरासत का उपयोग कार्य को हल करने का एक बहुत ही स्वाभाविक तरीका प्रतीत होता है। – ManuelAtWork

+1

कोई व्युत्पन्न 'बार' के बिना नहीं कर सकता है और सीधे 'foo :: myType1 mt1 {1} 'का उपयोग कर सकता है? – chi

+5

@chi - किया जा सकता है; बेस क्लास (आईएमएचओ) का उपयोग करने का लाभ यह है कि आप एक सरल और हल्की कक्षा के दो अलग-अलग विशेषज्ञताओं को केवल (या बिना) टाइपिफ़ के साथ विकसित कर सकते हैं; व्युत्पन्न कक्षा का एक संस्करण विकसित करने के लिए यह परमिट जटिल हो सकता है। – max66

15

दुर्भाग्यवश वांछित वाक्यविन्यास संभव नहीं हो सकता क्योंकि टेम्पलेट तत्कालता को पारित किए गए नाम पहले से ही परिभाषित किए जाने चाहिए। आपके मामले में myType1 और myType2 संकलक बिंदु दृश्य से कुछ भी नाम नहीं देंगे। लेकिन यदि आप वाक्य रचना आप उल्लेख किया है पर जोर नहीं कर रहे हैं आप के रूप में निम्नानुसार std::enable_if उपयोग करने के लिए कोशिश कर सकते:

#include <type_traits> 

struct A { 
    struct myType1: std::enable_if<true, int> { }; //std::conditional_typedef<true,int,myType1>; // Performs "typedef int myType1". 
    struct myType2: std::enable_if<false, int> { }; //std::conditional_typedef<false,int,myType2>; // Does nothing at all. 

}; 

int main() { 
    A::myType1::type i; 
    //A::myType2::type i2; // causes error: no type named 'type' in 'A::myType2' 
    (void)i; 
} 

[live demo]


संपादित करें:

फिर भी एक और तरीका है कि मेरे दिमाग में आया (डिफ़ॉल्ट टेम्पलेट पैरामीटर के साथ उपयोग करने का उपयोग):

#include <type_traits> 

struct A { 
    template <class T = int> 
    using myType1 = typename std::enable_if<true, T>::type; 
    template <class T = int> 
    using myType2 = typename std::enable_if<false, T>::type; 
}; 

int main() { 
    A::myType1<> i; 
    //A::myType2<> j; 
    (void)i; 
} 

[live demo]

2

इसी प्रकार की विशेषज्ञता से गुजर जा सकती है :: enable_if, आप अपने वर्ग हो सकता था अगर आप चाहते हैं कि आपके typedef करता है एक टेम्पलेट से उतरना अपने नामों का उपयोग करने के लिए और ए :: mytype1 :: प्रकार नहीं करना है। नकारात्मकता यह है कि यदि आप इसे बहुत करना चाहते हैं तो आपको कई structs से उतरना होगा।

namespace impl { 
    template<bool, typename> struct A; 
    template<typename T> struct A<true, T>{ typedef T mytype1; }; 
    template<typename T> struct A<false, T> {}; 
} 

struct A : public impl::A<condition, int> { 
    //If condition is met, then ::mytype1 will be defined as a typedef int 
}; 

int main() { 
    A::mytype1 i; //Will fail if condition wasn't met 
} 
संबंधित मुद्दे