2016-05-02 10 views
6

मेरे पास कक्षा Filter है जिसमें विभिन्न इनपुट के लिए process ओवरलोड किया गया है।उपनाम?

template< typename T > 
class Filter 
{ 
public: 
    void process(T arr[], size_t len); 
    T process(T one_value); 
    void process(std::array &arr); 
    void process(std::vector &v); 
    //... many other variants 

    using operator() = process; // How to write proper? 
} 

मैं process को छोड़ते हुए उपयोगकर्ता कोड को आसान बनाने में करना चाहते हैं: filter.process(values)filter(values) बन जाएगा। मुझे नहीं लगता कि प्रत्येक संस्करण के लिए एक ओवरलोडेड operator() लिखना अच्छा विचार है। एक और सुविधाजनक समाधान मौजूद होना चाहिए?

उत्तर

7

चूंकि आपके पास पहले से ही मिश्रण में टेम्पलेट हैं; एक भिन्न टेम्पलेट का प्रयास क्यों न करें;

template <typename... Args> 
auto operator()(Args&&... args) 
// assuming non-reference returns 
{ 
    return process(std::forward<Args>(args)...); 
} 

वैकल्पिक रूप से; यदि संदर्भ लौटाए गए हैं तो कुछ ओवरलोड (ओपी में दिखाया नहीं गया है);

template <typename... Args> 
decltype(auto) operator()(Args&&... args) 
// caters for reference returns 
{ 
    return process(std::forward<Args>(args)...); 
} 

आगे पूर्णता और व्यापक उपयोग के मामलों के लिए; यदि वांछित है, तो निम्नलिखित SFINAE- अनुकूल व्यवहार प्रदान करता है और संकलक, छोटे/आसान त्रुटि संदेशों के आधार पर;

template <typename... Args> 
auto operator()(Args&&... args) -> decltype(process(std::forward<Args>(args)...)) 
// SFINAE support using a trailing decltype 
{ 
    return process(std::forward<Args>(args)...); 
} 
+0

आप पूरी तरह से बाईपास प्रकार-चेकिंग संकलक द्वारा करना चाहते हैं और संभावित सूक्ष्म कीड़े का एक बहुत परिचय है, तो यकीन है कि, आगे बढ़ो हैं:

बस उन सभी भार के निर्माताओं में बजाय इतना की तरह करते हैं। –

+2

किसी भी प्रकार के चेक को बाईपास नहीं कर रहा है, कोई रूपांतरण नहीं है। 'ऑपरेशन' को 'ऑपरेटर() 'के लिए दिए गए तर्क प्राप्त होंगे। – Niall

+4

@ डैनकॉर्न मुझे लगता है कि सी ++ कोड के साथ 'सी ++' टैग का जवाब देना बहुत आम है जो मौजूदा मानक का पालन करता है। यही है, मुझे नहीं लगता कि 'सी ++' टैग सी ++ 03 या किसी अन्य विशिष्ट मानक का तात्पर्य है। –

8

ज़रूर, बस operator() टेम्पलेट, यूनिवर्सल संदर्भ का उपयोग करें, और process तर्क सही-आगे। कारण के लिए, आपको उपयुक्त शीर्षलेख जोड़ना होगा।

template< typename T > 
class Filter 
{ 
public: 
    void process(T arr[], size_t len); 
    T process(T one_value); 
    void process(std::array &arr); 
    void process(std::vector &v); 
    //... many other variants 

    template<typename... Y> 
    auto operator() (Y&&... y) 
     -> decltype(process(std::declval<Y>()...)) 
    { 
     return process(std::forward<Y>(y)...); 
    } 
} 

हालांकि, ध्यान दें कि process के हर अधिभार से पहले operator()(...) घोषित किया जाना चाहिए - धन्यवाद टीसी

+0

मुझे लगता है कि, मैं नेल के उत्तर में दिखाए गए अनुसार सी ++ 14 की बढ़ी हुई 'ऑटो' रिटर्न प्रकार कटौती की सादगी देखने के लिए अन्य लोगों के लिए अपना उत्तर छोड़ दूंगा। – WhiZTiM

+1

@ टी.सी. क्या हमें 'घोषणा' की ज़रूरत है? शायद बस 'decltype (प्रक्रिया (std :: आगे (वाई) ...))'? – Barry

-4

ठीक है, आप सवाल संपादित, तो यह अब तुम क्या पूछ रहे हैं जवाब, विशेष रूप से, "मैं चाहता हूँ उपयोगकर्ता कोड को छोड़ने की प्रक्रिया को सरल बनाएं: filter.process (मान) फ़िल्टर (मान) बन जाएंगे। "

template< typename T > 
class Filter 
{ 
public: 
    void Filter(T arr[], size_t len); 
    T Filter(T one_value); 
    void Filter(std::array &arr); 
    void Filter(std::vector &v); 
    //... many other variants 
}; 
+1

यह मेल नहीं खाता है कि ओपी फ़िल्टर को कॉल करना चाहता है। – NathanOliver

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