2008-11-16 1 views
48

में वैक्टरों के जेनेरिक वेक्टर क्या सी ++ में वेक्टर के जेनेरिक वेक्टर के लिए एक प्रकार (या नकली) लागू करने का कोई अच्छा तरीका है?सी ++

जब वेक्टर का वेक्टर एक अच्छा विचार है, तब तक इस मुद्दे को अनदेखा करें (जब तक कि कुछ समकक्ष हमेशा बेहतर न हो)। मान लें कि यह समस्या को सटीक रूप से मॉडल करता है, और यह कि मैट्रिक्स समस्या का सटीक रूप से मॉडल नहीं करता है। मान लें कि इन चीजों को ले जाने वाले टेम्पलेट किए गए कार्यों को पैरामीटर के रूप में करने की आवश्यकता होती है (उदा। पुश_बैक को कॉल करना), इसलिए वे केवल [][] का समर्थन करने वाला सामान्य प्रकार नहीं ले सकते हैं।

मुझे क्या करना चाहते हैं:

template<typename T> 
typedef vector< vector<T> > vecvec; 

vecvec<int> intSequences; 
vecvec<string> stringSequences; 

लेकिन निश्चित है कि संभव नहीं है, के बाद से typedef टेम्प्लेट नहीं किया जा सकता।

#define vecvec(T) vector< vector<T> > 

करीब है, और हर टेम्प्लेट समारोह जो vecvecs पर चल रही भर प्रकार डुप्लिकेट करने की बचत होगी, लेकिन सबसे सी ++ प्रोग्रामर के साथ लोकप्रिय नहीं होगा।

उत्तर

51

आप टेम्पलेट-टाइपिफ़ीज़ चाहते हैं। यह अभी तक वर्तमान C++ में समर्थित है। का संभावित हल

template<typename T> 
struct vecvec { 
    typedef std::vector< std::vector<T> > type; 
}; 

int main() { 
    vecvec<int>::type intSequences; 
    vecvec<std::string>::type stringSequences; 
} 

करने के लिए अगले सी ++ (C++ 0x, C++ 1x वजह से 2010 तक कहा जाता है) में है, यह संभव होगा:

template<typename T> 
using vecvec = std::vector< std::vector<T> >; 
+13

मुझे लगता है कि उन्होंने वास्तव में >> –

+0

में रिक्त स्थान की आवश्यकता भी तय की है, उनके पास है :) –

4

आप बस एक नया बना सकते हैं टेम्पलेट:

#include <string> 
#include <vector> 

template<typename T> 
struct vecvec : public std::vector< std::vector<T> > {}; 

int main() 
{ 
    vecvec<int> intSequences; 
    vecvec<std::string> stringSequences; 
} 

यदि आप वेक्टर की कि नाशक याद है कि आप आभासी नहीं है और इस तरह कुछ करने के लिए नहीं:

void test() 
{ 
    std::vector< std::vector<int> >* pvv = new vecvec<int>; 
    delete pvv; 
} 
+4

आप वेक्टर के सभी आसान रचनाकारों को खोने में भाग लेंगे। आपको माता-पिता को तर्क पारित करने, उन्हें परिभाषित करने की आवश्यकता है। एक संभावना है, लेकिन एक दुबला और मतलब समाधान नहीं है। – xtofl

+0

-1 उत्तर स्वयं अच्छी तरह से तैयार है और आप प्रस्तुत समाधान की प्रमुख त्रुटियों में से एक को इंगित करते हैं। हालांकि, यह दोष और अन्य डाउनवोट, मेथिंक के लिए पर्याप्त हैं। इस पुस्तकालय का उल्लेख करने के लिए –

5

मैं Boost.MultiArray का उपयोग करता हूं जो बूस्ट लाइब्रेरी में लागू होता है।

HTH

+0

+1 – mloskot

2

आप एक आधार के रूप std::vector का उपयोग करके बुनियादी वेक्टर के- वेक्टर प्रकार लागू कर सकते हैं:

#include <iostream> 
#include <ostream> 
#include <vector> 
using namespace std; 

template <typename T> 
struct vecvec 
{ 
    typedef vector<T> value_type; 
    typedef vector<value_type> type; 
    typedef typename type::size_type size_type; 
    typedef typename type::reference reference; 
    typedef typename type::const_reference const_reference; 

    vecvec(size_type first, size_type second) 
     : v_(first, value_type(second, T())) 
    {} 

    reference operator[](size_type n) 
    { return v_[n]; } 

    const_reference operator[](size_type n) const 
    { return v_[n]; } 

    size_type first_size() const 
    { return v_.size(); } 

    size_type second_size() const 
    { return v_.empty() ? 0 : v_[0].size(); } 

    // TODO: replicate std::vector interface if needed, like 
    //iterator begin(); 
    //iterator end(); 

private: 
    type v_; 

}; 

// for convenient printing only 
template <typename T> 
ostream& operator<<(ostream& os, vecvec<T> const& v) 
{ 
    typedef vecvec<T> v_t; 
    typedef typename v_t::value_type vv_t; 
    for (typename v_t::size_type i = 0; i < v.first_size(); ++i) 
    { 
     for (typename vv_t::size_type j = 0; j < v.second_size(); ++j) 
     { 
      os << v[i][j] << '\t'; 
     } 
     os << endl; 
    } 
    return os; 
} 

int main() 
{ 
    vecvec<int> v(2, 3); 
    cout << v.first_size() << " x " << v.second_size() << endl; 
    cout << v << endl; 

    v[0][0] = 1; v[0][1] = 3; v[0][2] = 5; 
    v[1][0] = 2; v[1][1] = 4; v[1][2] = 6; 
    cout << v << endl; 
} 

यह सिर्फ एक बहुत ही सरल कंटेनर कि जब तक एक मैट्रिक्स की नकल करता (उपयोगकर्ता वादे के रूप में है से vecvec परिभाषा में सुधार या उचित उपयोग, आयताकार आकार)।

+0

दुर्भाग्यवश एक मैट्रिक्स समस्या का मॉडल नहीं करता है। डेटा "आयताकार" नहीं है, अलग-अलग पंक्तियां अलग-अलग लंबाई के हैं। –

+0

@ स्टेव जेसॉप - आम तौर पर, वेक्टर के वेक्टर के साथ काम करते समय, हां पुश_बैक इत्यादि के संपर्क की वजह से ऐसी घटना होती है, लेकिन यह एक उदाहरण, एक प्राचीन समाधान माना जाता है और मैंने पाठक में सुधार छोड़ा, यानी सामान्य गारंटी पंक्तियों के लिए आकार बनाए रखा जाता है, न कि उन परिचालनों का पर्दाफाश करना जो पंक्ति वेक्टर के आयाम को संशोधित कर सकते हैं आदि। – mloskot