2013-05-18 9 views
5

std::enable_if में गैर-प्रकार टेम्पलेट पैरामीटर तुलना का उपयोग करने के बारे में आप कैसे जाएंगे? मैं यह नहीं समझ सकता कि इसे फिर से कैसे किया जाए। (मैंने एक बार यह काम किया था, लेकिन मैंने कोड खो दिया है, इसलिए मैं इसे वापस नहीं देख सकता, और मुझे वह पद नहीं मिल रहा है जिसमें मुझे जवाब मिला है।)std :: enable_if गैर-प्रकार टेम्पलेट पैरामीटर्स

किसी भी मदद के लिए अग्रिम धन्यवाद यह विषय।

template<int Width, int Height, typename T> 
class Matrix{ 
    static 
    typename std::enable_if<Width == Height, Matrix<Width, Height, T>>::type 
    Identity(){ 
     Matrix ret; 
     for (int y = 0; y < Width; y++){ 
      elements[y][y] = T(1); 
     } 
     return ret; 
    } 
} 

संपादित करें: फिक्स्ड लापता ब्रैकेट के रूप में टिप्पणी में कहा।

+3

मैं शायद इसके लिए 'static_assert' का उपयोग करूंगा। यह स्पष्ट त्रुटि संदेश प्रदान करता है। – chris

+0

'static_assert' वास्तव में सही उपकरण है: 'std :: enable_if' SFINAE के लिए है, और क्लास टेम्पलेट के गैर-टेम्पलेट सदस्य के लिए कोई SFINAE संभव नहीं है। –

+0

मैंने 'static_assert' का उपयोग करने के बारे में सोचा है, अंततः मैं इसका उपयोग कर समाप्त कर सकता हूं। लेकिन मैंने पहले यह काम किया था, और ऑटो पूर्ण होने के लाभ के साथ पहले स्थान पर गैर स्क्वायर मैट्रिस के लिए फ़ंक्शन सूचीबद्ध नहीं किया गया था। हालांकि, इस बिंदु पर बड़े पैमाने पर यह पता लगाने की कोशिश कर रहा है कि मैंने इसे एक बार 'std :: enable_if' के साथ कैसे किया था। – LostOfThought

उत्तर

3

यह सब इस बात पर निर्भर करता है कि आप किस प्रकार की त्रुटि/विफलता को अमान्य कोड पर उठाना चाहते हैं। यहाँ यह एक संभावना

(सी ++ 98 शैली) (एक तरफ स्पष्ट static_assert(Width==Height, "not square matrix"); छोड़कर) है

#include<type_traits> 
template<int Width, int Height, typename T> 
class Matrix{ 
    public: 
    template<int WDummy = Width, int HDummy = Height> 
    static typename std::enable_if<WDummy == HDummy, Matrix<Width, Height, T> >::type 
    Identity(){ 
    Matrix ret; 
    for (int y = 0; y < Width; y++){ 
    // elements[y][y] = T(1); 
     } 
     return ret; 
    } 
}; 

int main(){ 
    Matrix<5,5,double> m55; 
    Matrix<4,5,double> m45; // ok 
    Matrix<5,5, double> id55 = Matrix<5,5, double>::Identity(); // ok 
// Matrix<4,5, double> id45 = Matrix<4,5, double>::Identity(); // compilation error! 
//  and nice error: "no matching function for call to ‘Matrix<4, 5, double>::Identity()" 
} 

संपादित करें: सी ++ 11 में कोड, अधिक कॉम्पैक्ट और स्पष्ट हो सकता है (यह clang 3.2 में लेकिन gcc 4.7.1 में नहीं काम करता है, तो मुझे यकीन है कि यह कैसे मानक है) नहीं कर रहा हूँ:

(सी ++ 11 शैली)

template<int Width, int Height, typename T> 
class Matrix{ 
    public: 
     template<typename = typename std::enable_if<Width == Height>::type> 
     static Matrix<Width, Height, T> 
     Identity(){ 
     Matrix ret; 
     for (int y = 0; y < Width; y++){ 
     //  ret.elements[y][y] = T(1); 
     } 
     return ret; 
    } 
}; 
+0

बस मुझे इस सवाल पर अपना जवाब खत्म करने के लिए हराया। बिना किसी जवाब के उत्तर के लिए धन्यवाद। स्वीकृत के रूप में चिह्नित। – LostOfThought

+1

सी ++ में एक और कॉम्पैक्ट विकल्प है: 'टेम्पलेट :: प्रकार> स्थिर मैट्रिक्स पहचान() {... } ' – alfC

+0

क्या 'WDummy' भी आवश्यक है? एमएसवीसी: सीटीपी नवंबर '12 के साथ/डब्ल्यू 4 इसके बिना बस ठीक है। – LostOfThought

1

मुझे यहां मेरे प्रश्न का उत्तर मिला: Using C++11 std::enable_if to enable...

मेरे समाधान में, SFINAE मेरे टेम्पलेटेड रिटर्न प्रकार के भीतर होता है, इसलिए फ़ंक्शन टेम्पलेट स्वयं मान्य है। इसके दौरान, कार्य स्वयं भी templated हो जाता है।

template<int Width, int Height, typename T> 
class Matrix{ 
    template<typename EnabledType = T> 
     static 
     typename Matrix<Width, Height, 
      typename std::enable_if<Width == Height, EnabledType>::type> 
     Identity(){ 
     Matrix ret; 
     for (int y = 0; y < Width; y++){ 
      ret.elements[y][y] = T(1); 
     } 
     return ret; 
    } 
} 
+0

मैंने एक और कॉम्पैक्ट संस्करण जोड़ा मेरा जवाब, लेकिन यह 'gcc' में काम नहीं करता है। बीटीडब्लू, 'मैट्रिक्स' से पहले 'टाइपनाम' सबसे अच्छा अनावश्यक है। – alfC

+0

आपके संपादन में कोड मेरे नए उत्तर के जैसा ही है, यहां इसे दोहराने में कोई बात नहीं है। – alfC

+0

मैं अब देखता हूं। इरादा नहीं था मैं पूरी रात इस कोड के साथ गड़बड़ कर रहा हूँ, मैं वास्तव में ऊब गया हूँ। भले ही, आपकी मदद के लिए धन्यवाद। – LostOfThought

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