2010-02-18 9 views
6

आइए कल्पना करें कि मैं एक टेम्पलेट फ़ंक्शन बनाना चाहता हूं जो किसी भी एसटीएल कंटेनर का पहला तत्व लौटाता है। सामान्य तरीका होगा:टेम्पलेट पैरामीटर एक जोड़ी सहयोगी कंटेनर है या नहीं, तो परीक्षण कैसे करें?

template<typename Container> 
Container::value_type first(Container c){ 
    return *(c.begin()); 
} 

यह वैक्टर, सूचियों, डेक, सेट आदि के लिए काम करता है।

हालांकि, जोड़ी साहचर्य कंटेनर (std :: नक्शा) के लिए, अगर करना चाहते हैं

return c.begin()->second; 

मैं कैसे परीक्षण कर सकते हैं (समारोह में या टेम्पलेट विशेषज्ञता के साथ) अगर मैं एक जोड़ी साहचर्य कंटेनर है?

एसटीएल कंटेनर के पास कोई विशेषता नहीं है। क्या यह जांचना संभव है कि इसमें :: key_type है या नहीं?

उत्तर

3

आप काफी आसानी से कर सकते हैं:

namespace result_of // pillaged from Boost ;) 
{ 
    template <class Value> 
    struct extract { typedef Value type; }; 

    template <class First, class Second> 
    struct extract < std::pair<First,Second> > { typedef Second type; }; 
} 

template <class Value> 
Value extract(Value v) { return v; } 

template <class First, class Second> 
Second extract(std::pair<First,Second> pair) { return pair.second; } 

template <class Container> 
typename result_of::extract< typename Container::value_type >::type 
first(const Container& c) { return extract(*c.begin()); } 

मैं हालांकि ध्यान देना चाहिए, कि मैं शायद एक परीक्षण जोड़ना होगा देखने के लिए कि कंटेनर empty है ... क्योंकि अगर कंटेनर empty है, तो आप पर हैं अपरिभाषित व्यवहार के लिए।

आंदोलन में:

int main(int argc, char* argv[]) 
{ 
    std::vector<int> vec(1, 42); 
    std::map<int,int> m; m[0] = 43; 
    std::cout << first(vec) << " " << first(m) << std::endl; 
} 

// outputs 
// 42 43 

उदाहरण बेशर्म litb से लिया;)

+0

अच्छा जवाब। इसे संकलित करने के लिए, ';' structs के अंत में गायब हैं और .front() –

+0

ओप्स के लिए काम नहीं करता है, जो आपको थोड़ा तेज़ उत्तर देने से मिलता है: मैंने गायब ';' जोड़ा है और एक 'रेफरेंस' 'शुरू करें' :) –

3

यह एक काम करता है:

template<typename T> 
struct tovoid { 
    typedef void type; 
}; 

template<typename T, typename = void> 
struct value_type { 
    typedef typename T::value_type type; 
    static type get(T const& t) { 
    return *t.begin(); 
    } 
}; 

template<typename T> 
struct value_type<T, typename tovoid<typename T::mapped_type>::type> { 
    typedef typename T::mapped_type type; 
    static type get(T const& t) { 
    return t.begin()->second; 
    } 
}; 

template<typename Container> 
typename value_type<Container>::type first(Container const& c){ 
    return value_type<Container>::get(c); 
} 

int main() { 
    std::map<int, int> m; m[0] = 42; std::cout << first(m); 
    std::vector<int> a(1, 43); std::cout << first(a); 
} 

(आउटपुट 4243) टेम्पलेट समारोह की विशेषज्ञता

1

का उपयोग करें:

template<typename Container> 
typename Container::value_type first(typename Container c) 
{ 
    return *(c.begin()); 
} 


template<typename K, typename V> 
typename V first(std::map<K,V> & c) 
{ 
    return c.begin()->second; 
} 
संबंधित मुद्दे

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