2012-08-28 18 views
11

निम्नलिखित कोड पर विचार करें:यदि संकलन समय पर/else?

#include <iostream> 
#include <type_traits> 

template<typename T> class MyClass 
{ 
    public: 
     MyClass() : myVar{0} {;} 
     void testIf() { 
      if (isconst) { 
       myVar; 
      } else { 
       myVar = 3; 
      } 
     } 
     void testTernary() { 
      (isconst) ? (myVar) : (myVar = 3); 
     } 

    protected: 
     static const bool isconst = std::is_const<T>::value; 
     T myVar; 
}; 

int main() 
{ 
    MyClass<double> x; 
    MyClass<const double> y; 
    x.testIf(); 
    x.testTernary(); 
    y.testIf(); // <- ERROR 
    y.testTernary(); // <- ERROR 
    return 0; 
} 

एक्स (गैर स्थिरांक) के लिए वहाँ कोई समस्या नहीं है। लेकिन वाई (कॉन्स डेटा प्रकार) एक त्रुटि का कारण बनता है भले ही स्थिति/समय में संकलन समय पर ज्ञात हो।

क्या संकलन समय पर झूठी स्थिति को संकलित करने की कोई संभावना नहीं है?

+4

क्या आप चाहते हैं एक 'स्थिर if' है, और यह हिस्सा नहीं है सी ++ के अभी तक (http://channel9.msdn.com/Events/GoingNative/GoingNative-2012/Static-If-I-Had-a- हथौड़ा) – arnoo

उत्तर

11

सरल ठीक है आंशिक टेम्पलेट विशेषज्ञता:

template<typename T> class MyClass 
{ 
    public: 
     MyClass() : myVar{0} {;} 
     void testIf() { testIf_impl(std::integral_constant<bool, isconst>()); } 

    protected: 
     static const bool isconst = std::is_const<T>::value; 
     T myVar; 

    private: 
     void testIf_impl(std::true_type) { myvar; } 
     void testIf_impl(std::false_type) { myVar = 3; } 
}; 
:

template<typename T> class MyClassBase 
{ 
    public: 
     MyClassBase() : myVar{0} {;} 

    protected: 
     T myVar; 
}; 

template<typename T> class MyClass: MyClassBase<T> 
{ 
    public: 
     void testIf() { myVar = 3; } 
}; 

template<typename T> class MyClass<const T>: MyClassBase<const T> 
{ 
    public: 
     void testIf() { myVar; } 
}; 

एक अन्य विकल्प प्रतिनिधिमंडल है

एसएफआईएनएई एक और विकल्प है, लेकिन आमतौर पर इसे पसंद नहीं किया जाता है या इस मामले:

template<typename T> class MyClass 
{ 
    public: 
     MyClass() : myVar{0} {;} 
     template 
     <typename U = void> 
     typename std::enable_if<std::is_const<T>::value, U>::type testIf() { myvar; } 
     template 
     <typename U = void> 
     typename std::enable_if<!std::is_const<T>::value, U>::type testIf() { myvar = 3; } 

    protected: 
     static const bool isconst = std::is_const<T>::value; 
     T myVar; 
}; 
1

यदि अन्य शाखा संकलित नहीं की गई थी, तो आपके कार्य का एक अलग अर्थ होगा। आप बस अपने कोड का हिस्सा संकलित नहीं कर सकते हैं। यदि आप इसे निष्पादित नहीं करना चाहते हैं, तो इसे मत लिखें। ऐसा नहीं है कि प्रत्येक बार इसे कॉल करने के लिए फ़ंक्शन को अलग से संकलित किया जाता है।

एक प्रकार की प्रणाली का पूरा बिंदु const चरों को असाइन करने जैसी चीजों को करने की कोशिश कर रहा है। आपको एक बिल्कुल नया (या ओवरलोडेड) फ़ंक्शन लिखना होगा जो उस चर को असाइन नहीं करता है।

3

कक्षा टेम्पलेट दिए गए प्रकार के लिए संकलित हो जाता है। यहां तक ​​कि यदि नियंत्रण प्रवाह असाइनमेंट तक नहीं मिलता है, तो वह असाइनमेंट भी संकलित किया जाता है। चूंकि सदस्य स्थिर है, संकलन विफल हो जाएगा।

आप उस असाइनमेंट को छोड़ने के लिए SFINAE के कुछ रूपों का उपयोग कर सकते हैं, लेकिन यह अब काम करने वाला नहीं है।

यह काम करता है (मैं सादगी के लिए testTernary सदस्य समारोह को हटा दिया है):

#include <iostream> 
#include <type_traits> 

template<typename T> class MyClass 
{ 
    public: 
     MyClass() : myVar{0} {;} 

     template<class U = T> 
     typename std::enable_if<std::is_const<U>::value>::type testIf() { 
      myVar; 
     } 

     template<class U = T> 
     typename std::enable_if<!std::is_const<U>::value>::type testIf() { 
      myVar = 3; 
     } 

    protected: 
     static const bool isconst = std::is_const<T>::value; 
     T myVar; 
}; 

int main() 
{ 
    MyClass<double> x; 
    MyClass<const double> y; 
    x.testIf(); 
    y.testIf(); 
    return 0; 
} 
5

आप स्थिरांक प्रकार के लिए वर्ग विशेषज्ञ कर सकते हैं

template<typename T> 
class MyClass 
{ 
    // Whatever you need to do 
}; 

template<typename T> 
class MyClass<const T> 
{ 
    // Whatever you need to do for const types 
}; 
0

इस प्रयास करें:

template<typename T> 
class MyClass 
{ 
    T myVar; 
public: 
    MyClass() : myVar(0) {} 

    void testIf() 
    { 
     assign(myVar, 3); 
    } 
private: 

    template<typename V> 
    void assign(V& destination, int value) 
    { 
     destination = value; 
    } 
    template<typename V> 
    void assign(const V& destination, int value) 
    { 

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