2015-05-21 15 views
9

मैं एक फ़ंक्शन लिख रहा हूं जिसमें से एक (std::map, std::multimap, std::unordered_map या std::unordered_multimap) प्राप्त करना चाहिए। मेरे कोड इस प्रकार है:किसी भी मानक मानचित्र को प्राप्त करने वाला फ़ंक्शन टेम्पलेट

template<template <class, class> class Map, typename Coord> 
    inline typename std::enable_if<std::is_arithmetic<Coord>::value>::type 
    filter(Map<Coord, Coord>& map, Coord step = 2) { 
      for (auto it = std::begin(map); it != std::end(map);) { 
       if (it->second - it->first <= step){ 
        it = map.erase(it); 
       } 
       else 
        ++it; 
      } 
     } 

टेम्पलेट टेम्पलेट पैरामीटर Map नक्शे के सभी प्रकार के लिए सामान्य नहीं है। std::map और std::multimap चार टेम्पलेट पैरामीटर प्राप्त करते हैं, और std::unordered_map और std::unordered_multimap पांच टेम्पलेट पैरामीटर प्राप्त करते हैं। इसका तात्पर्य है कि मैं टेम्पलेट टेम्पलेट पैरामीटर के साथ समस्या का समाधान नहीं कर सकता। क्या इस समस्या को हल करने का कोई तरीका है कि सभी मानचित्रों में KeyType = ValeType = Coord होना चाहिए? मैं filter पर कॉल में पैरामीटर प्रकारों को स्पष्ट रूप से निर्दिष्ट नहीं करना चाहता हूं।

उत्तर

1

हालांकि उन टेम्पलेट वर्गों में तर्कों की एक अलग संख्या होती है, उनके पास डिफ़ॉल्ट हैं, इसलिए सभी को केवल दो के साथ तुरंत चालू किया जा सकता है। जैसे, तुम सिर्फ एक variadic टेम्पलेट का उपयोग कर सकता है, तो कुछ भी जो दो तर्कों instantiatable नहीं है वैसे भी एक संकलक त्रुटि में परिणाम होगा:

template <typename M, typename COORD> 
struct is_map_of_coord : std::false_type { }; 

:

template<template <class...> class Map, typename Coord> 
+0

यह आपको मानता है एक अलग ऑर्डरिंग फ़ंक्शन, या डिफ़ॉल्ट से अलग हैश के साथ मानचित्र का समर्थन नहीं करना चाहते हैं। जो अजीब लगता है। – Yakk

4

बस अपने खुद के प्रकार विशेषता बारे में आप तो 5 नक्शे के लिए विशेषज्ञ यही कारण है कि:

template <typename COORD, typename C, typename A> 
struct is_map_of_coord<std::map<COORD, COORD, C, A>, COORD> 
: std::true_type { }; 

template <typename COORD, typename H, typename K, typename A> 
struct is_map_of_coord<std::unordered_map<COORD, COORD, H, K, A>, COORD> 
: std::true_type { }; 

etc. 

आप जब तक यहहै किसी भी map स्वीकार करते हैं, इसके संभाजक, तुलनित्र, हैश समारोह की परवाह किए बिना, आदि, की सुविधा देता है कौन सा/ValueCoord हैं:

template <typename Map, typename Coord = int> 
inline typename std::enable_if< 
    std::is_arithmetic<Coord>::value && 
    is_map_of_coord<Map, Coord>::value 
>::type 
filter(Map& map, Coord step = 2) { 
    /* body */ 
} 

या आप छोटा कर सकते हैं कि सिर्फ इतना है कि यह सोचते द्वारा के बाद से सभी नक्शे एक key_type और mapped_type है, कि उन की पुष्टि दोनों मौजूद हैं और कर रहे हैं एक ही COORD के रूप में:

template <typename...> 
using void_t = void; 

template <typename M, typename COORD, typename = void> 
struct is_map_of_coord : std::false_type { }; 

template <typename M, typename COORD> 
struct is_map_of<M, K, void_t< 
    std::enable_if_t<std::is_same<typename M::key_type, COORD>::value>, 
    std::enable_if_t<std::is_same<typename M::mapped_type, COORD>::value> 
> > 
: std::true_type 
{ }; 
+0

'कोऑर्ड' के लिए प्रतिस्थापन का अनुमान नहीं लगा सकता है, स्पष्ट रूप से निर्दिष्ट करना होगा। –

+0

@RaulAlonso बस अपडेट करने के लिए 'कोऑर्ड' के लिए एक डिफ़ॉल्ट प्रकार जोड़ना होगा। – Barry

4

आपने सी ++ 11 टैग किया है, इसलिए मैं वैरिएडिक टेम्पलेट पैरामीटर का उपयोग करने की कोशिश करूंगा:

template<template <class ... > class Map, typename Coord, typename ... MapParms > 
inline typename std::enable_if<std::is_arithmetic<Coord>::value>::type 
filter(Map<Coord, Coord, MapParms... >& map, Coord step = 2) 
{ 
    for (auto it = std::begin(map); it != std::end(map);) 
    { 
     if (it->second - it->first <= step) 
     { 
      it = diagram.erase(it); 
     } 
     else 
     { 
      ++it; 
     } 
    } 

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