2015-05-25 10 views
14

के आधार पर विभिन्न कार्यों का निष्पादन करें यह निश्चित रूप से एक मामूली सवाल है, लेकिन मैं यह नहीं समझ पाया कि यह कैसे करें।टेम्पलेट पैरामीटर विचलन

मेरे पास एक टेम्पलेट फ़ंक्शन है, template <unsigned int N> void my_function() कहें। अब, मेरे पास my_function के लिए दो अलग-अलग कार्यान्वयन हैं, पहले उपयोग किया जाना चाहिए यदि N 0 से बड़ा है, तो दूसरा, N उससे छोटा है।

मैं इस तरह SFINAE का उपयोग करने की कोशिश की:

template <unsigned int N, typename = enable_if <N >= 100> :: type> my_function() 
{ 
    // First implementation 
} 

template <unsigned int N, typename = enable_if <N < 100> :: type> my_function() 
{ 
    // Second implementation 
} 

लेकिन उसी समारोह दो बार की घोषणा की है। फिर मैंने

template <unsigned int N, bool = (N >= 100)> my_function(); 

और फिर बूलियन के दो अलग-अलग मूल्यों के साथ दो कार्यों को कार्यान्वित करने की कोशिश की। कोई सफलता नहीं, क्योंकि यह आंशिक विशेषज्ञता है।

फिर मैंने N को एक संरचना पैरामीटर के रूप में लपेटने की कोशिश की, और फ़ंक्शन कॉल में बूल, लेकिन यह क्लास को विशेषज्ञता देने से पहले सदस्य फ़ंक्शन को विशेषज्ञता दे रहा है, जो नहीं किया जा सकता है।

क्या ऐसा करने का कोई उचित तरीका है?

उत्तर

12

ऐसा करें:

#include <type_traits> 
#include <iostream> 

template <unsigned int N, typename std::enable_if <N >= 100> :: type* = nullptr> 
void my_function() 
{ 
    std::cout << "N >= 100" << std::endl; 
} 

template <unsigned int N, typename std::enable_if <N < 100> :: type* = nullptr> 
void my_function() 
{ 
    std::cout << "N < 100" << std::endl; 
} 

int main() 
{ 
    my_function<42>(); 
    my_function<100>(); 
} 

Template default parameters do not participate in the overload (और इसलिए SFINAE लागू नहीं होता)। दूसरी ओर, ऊपर स्निपेट में निर्भर टेम्पलेट गैर प्रकार पैरामीटर असाइनमेंट के बाएं हाथ की ओर है, तो SFINAE में किक है

2

आप वापसी प्रकार पर SFINAE उपयोग कर सकते हैं:।

template <unsigned int N> 
enable_if_t<(N >= 100)> my_function() 
{ 
    // First implementation 
} 

template <unsigned int N> 
enable_if_t<(N < 100)> my_function() 
{ 
    // Second implementation 
} 

वर्तमान में, आपके पास template <unsigned int N, typename T> है जो T के लिए अलग-अलग डिफ़ॉल्ट प्रकार के साथ है।

आंशिक विशेषज्ञता के लिए, आप संरचना करने के लिए अग्रेषित कर सकते हैं:

template <unsigned int N, bool = (N >= 100)> 
struct my_function_impl; 

template <unsigned int N> 
struct my_function_impl<N, true> 
{ 
    void operator() const { /* First implementation */} 
}; 

template <unsigned int N> 
struct my_function_impl<N, false> 
{ 
    void operator() const { /* Second implementation */} 
}; 

template <unsigned int N> 
void my_function() { my_function_impl<N>{}(); } 
5

आप किसी कारण से enable_if पसंद नहीं है, तो आप हमेशा टैग प्रेषण के लिए जा सकते हैं:

#include <type_traits> 
class low {}; 
class high {}; 
template <int N, class T> 
    void func(T, low) 
    { 
     // version for high N 
    } 
template <int N, class T> 
    void func(T, high) 
    { 
     // version for low N 
    } 
template <int N, class T> 
    void func(T val) 
    { 
     func<N>(val, std::conditional_t<(N>=100), high, low>{}); 
    } 
int main() 
{ 
    func<3>(3.14159); // low version 
    func<256>("Yo"); // high version 
} 

इस में मामला, हम टैग को सरल चीजों जैसे true_type और false_type तक सीमित कर सकते हैं, लेकिन सामान्य रूप से यह एक वैकल्पिक दृष्टिकोण हो सकता है।

+0

मुझे यह पसंद है! अगली बार मैं इसका इस्तेमाल करूंगा, धन्यवाद! –

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