2012-12-20 49 views
23

के साथ त्रुटि क्यों संकलित करें यह gcc48 और clang32 के साथ संकलित क्यों नहीं है?enable_if

#include <type_traits> 

template <int N> 
struct S { 

    template<class T> 
    typename std::enable_if<N==1, int>::type 
    f(T t) {return 1;}; 

    template<class T> 
    typename std::enable_if<N!=1, int>::type 
    f(T t) {return 2;}; 
}; 

int main() { 
    S<1> s1; 
    return s1.f(99); 
} 

जीसीसी त्रुटि:

/home/lvv/p/sto/test/t.cc:12:2: error: no type named ‘type’ in ‘struct enable_if<false, int>’ 
    f(T t) {return 2;}; 
^

बजना त्रुटि:

/home/lvv/p/sto/test/t.cc:11:26: error: no type named 'type' in 'std::enable_if<false, int>'; 'enable_if' cannot be used to 
     disable this declaration 
     typename std::enable_if<N!=1, int>::type 
           ^~~~ 
/home/lvv/p/sto/test/t.cc:16:7: note: in instantiation of template class 'S<1>' requested here 
     S<1> s1; 
      ^

संपादित करें - समाधान

मैं चार्ल्स साल्विया से जवाब स्वीकार कर लिया है, लेकिन व्यावहारिक कारणों के लिए मैं प्रस्तावित कार्यवाही का उपयोग करने में सक्षम नहीं था (एन पर विशेषज्ञ)। मुझे अन्य कामकाज मिला जो मेरे लिए काम करता है।

typename std::enable_if<(sizeof(T),N==1), int>::type 
+1

आप यकीन है कि यह वैसे भी काम करने के लिए जा रहा है कर रहे हैं? आप अपने रिटर्न प्रकार से केवल विधियों को अधिभारित नहीं कर सकते हैं (जब तक कि 'enable_if' को भाषा निर्माण के रूप में कार्यान्वित नहीं किया जाता है, जैसा कि मैं वर्तमान में मान रहा हूं, एक साधारण टेम्पलेट क्लास)। – zneak

+0

enable_if को बनाने के कामकाज को टी पर निर्भर क्यों है, बिल्कुल? –

+0

समाधान मेरे लिए काम नहीं करता है! मुझे त्रुटि मिली: कॉल के लिए कोई मिलान करने वाला फ़ंक्शन नहीं ... ' –

उत्तर

14

क्योंकि आप अपनी समारोह टेम्पलेट्स में टेम्पलेट पैरामीटर T का उपयोग किए बिना enable_if का उपयोग करें: enable_ifT पर निर्भर करते हैं। यदि आप S पर एक निश्चित टेम्पलेट पैरामीटर मान N के लिए विशेषज्ञ बनाना चाहते हैं, तो आपको कक्षा टेम्पलेट विशेषज्ञता का उपयोग करना होगा।

template <int N, class Enable = void> 
struct S { }; 

template <int N> 
struct S<N, typename std::enable_if<N == 1>::type> 
{ 
    .... 
}; 
5

std::enable_if प्राप्त करने के लिए इस तरह काम करने के लिए, आप SFINAE पर भरोसा कर रहे हैं। दुर्भाग्य से, बिंदु पर जहां घोषित

S<1> s1; 

यह S<1> के सदस्य घोषणाओं के सभी का दृष्टांत होगा। SFINAE केवल इस बिंदु पर खेलेंगे यदि S<1> एक खराब गठित निर्माण थे। यह नहीं। दुर्भाग्यवश, इसमें एक फ़ंक्शन है जो अमान्य है, इस प्रकार S<> का तत्काल अमान्य है। इस मामले आप बिल्कुल enable_if का उपयोग नहीं के बारे में सोच सकता है के लिए

template <bool B> 
struct f_functor { 
    template <typename T> 
    static int f(T t) { return 1; } 
}; 

template <> 
struct f_functor<false> { 
    template <typename T> 
    static int f(T t) { return 2; } 
}; 

template <int N> 
struct S { 

    template<class T> 
    typename int f(T t) { return f_functor<N==1>::f(t); } 
}; 
+1

[यह सवाल] (http: // stackoverflow।कॉम/प्रश्न/6972368/stdenable-if-to-condition-compile-a-member-function) में कुछ और जानकारी है। – Anthony

1

:

इस तरह बातें के लिए, मैं एक अलग टेम्पलेट struct के लिए स्थगित हो सकता है। ,

template <int N> 
struct S { 
    template<class T> int f(T t); 
}; 

template<int N> 
template<class T> 
int S<N>::f(T t) { return 2; } 

template<> 
template<class T> 
int S<1>::f(T t) { return 1; } 

int main() { 
    S<1> s1; 
    return s1.f(99); 
} 
6

एक डिफ़ॉल्ट बूलियन टेम्पलेट पैरामीटर का उपयोग इस तरह::

template <int N> 
struct S { 

    template<class T, bool EnableBool=true> 
    typename std::enable_if<N==1 && EnableBool, int>::type 
    f(T t) {return 1;}; 

    template<class T, bool EnableBool=true> 
    typename std::enable_if<N!=1 && EnableBool, int>::type 
    f(T t) {return 2;}; 
}; 
7

ठीक है, मुझे यकीन है कि आप क्या करना चाहते थे नहीं कर रहा हूँ, लेकिन शायद इस कोड को मदद मिलेगी यह बस च विशेषज्ञ posible है :

#include <iostream> 

template <int N> 
struct S { 

    template<class T=int> 
    typename std::enable_if<N==1, T>::type 
    f(T t) {return 1;} 

    template<class T=int> 
    typename std::enable_if<N!=1, T>::type 
    f(T t) {return 2;} 
}; 

int main() 
{ 
    S<1> s1; 
    S<2> s2; 
    std::cout << s1.f(99) << " " << std::endl << s2.f(5); 
} 

यह प्रिंट 1 और 2