दिलचस्प पोस्ट
बंडल स्थापित / अद्यतन: libv8 (थर्मिब्रेसर) स्थापना विफल (मूल एक्सटेंशन के साथ) जावा के भीतर से अजगर का उपयोग करना एंड्रॉइड अनजान कमांड 'क्रॉंच' Github पुश त्रुटि: RPC विफल; परिणाम = 22, एचटीपी कोड = 413 मणि देशी एक्सटेंशन (कम्पास स्थापित करने) बनाने में विफल mysqli आखिरी प्रविष्टि आईडी मैं कैसे अपने सी + + प्रोग्राम में हेडर फाइल <graphics.h> प्राप्त कर सकता हूं और उपयोग कर सकता हूं? एक SQLite क्वेरी में LIMIT कथन का उपयोग करना NoSQL स्टोर में छवियों को संग्रहीत करना प्रो Xcode डेवलपर आईडी तैयार पीकेजी जैसे ओएस एक्स इंस्टालर पैकेज बनाना क्या पठार म्यूटिक्स की गारंटी के साथ एक वेरिएबल को सुरक्षित रखता है, यह कैश्ड नहीं है? ASP.NET वेब प्रपत्र में jQuery के सत्यापन प्लगइन कोशिश की और सी में सरल सरल फ़ाइल कॉपी कोड? CSS3 पारदर्शिता + ढाल पृष्ठभूमि में StartUpdateLocations, अपग्रेडिंगटोक स्थान केवल 10-20 बार कहा जाता है

ऑपरेटर अधिभार

क्या यह अधिभार [] ऑपरेटर के लिए दो बार संभव है? अनुमति देने के लिए, ऐसा कुछ: function[3][3] (जैसे कि दो आयामी सरणी में)

यदि यह संभव है, तो मुझे कुछ उदाहरण कोड देखना है।

Solutions Collecting From Web of "ऑपरेटर अधिभार"

आप operator[] को लोड कर सकते हैं operator[] एक ऑब्जेक्ट वापस करने के लिए जिस पर आप operator[] फिर से परिणाम प्राप्त कर सकते हैं।

 class ArrayOfArrays { public: ArrayOfArrays() { _arrayofarrays = new int*[10]; for(int i = 0; i < 10; ++i) _arrayofarrays[i] = new int[10]; } class Proxy { public: Proxy(int* _array) : _array(_array) { } int operator[](int index) { return _array[index]; } private: int* _array; }; Proxy operator[](int index) { return Proxy(_arrayofarrays[index]); } private: int** _arrayofarrays; }; 

तो आप इसे इस तरह उपयोग कर सकते हैं:

 ArrayOfArrays aoa; aoa[3][5]; 

यह सिर्फ एक सरल उदाहरण है, आप चेकिंग और सामग्री की सीमा को जोड़ना चाहते हैं, लेकिन आपको यह विचार मिलता है।

एक अभिव्यक्ति x[y][z] आवश्यक है कि x[y] एक ऑब्जेक्ट का मूल्यांकन करता है जो d[z] का समर्थन करता है।

इसका अर्थ है कि x[y] एक operator[] साथ एक वस्तु होना चाहिए जो "प्रॉक्सी ऑब्जेक्ट" का मूल्यांकन करता है जो operator[] का भी समर्थन करता है operator[]

यह उनको श्रृंखलाबद्ध करने का एकमात्र तरीका है

वैकल्पिक रूप से, अतिभारित operator() कई तर्कों को लेने के लिए, जैसे कि आप myObject(x,y) को लागू कर सकते हैं।

यदि आप पहले [] कॉल में कुछ प्रकार की प्रॉक्सी क्लास वापस करते हैं, तो यह संभव है। हालांकि, एक अन्य विकल्प है: आप ओवरलोड ऑपरेटर () कर सकते हैं जो किसी भी संख्या में तर्क ( function(3,3) ) स्वीकार कर सकते हैं।

एक दो आयामी सरणी के लिए, विशेष रूप से, आप एक एकल ऑपरेटर [] अधिभार के साथ भाग ले सकते हैं जो प्रत्येक पंक्ति के पहले तत्व को सूचक देता है।

फिर आप पंक्ति में प्रत्येक तत्व को एक्सेस करने के लिए अंतर्निहित अनुक्रमणिका ऑपरेटर का उपयोग कर सकते हैं।

एक दृष्टिकोण std::pair<int,int> :

 class Array2D { int** m_p2dArray; public: int operator[](const std::pair<int,int>& Index) { return m_p2dArray[Index.first][Index.second]; } }; int main() { Array2D theArray; pair<int, int> theIndex(2,3); int nValue; nValue = theArray[theIndex]; } 

बेशक, आप pair<int,int> typedef कर सकते हैं

आप प्रॉक्सी ऑब्जेक्ट का उपयोग कर सकते हैं, ऐसा कुछ:

 #include <iostream> struct Object { struct Proxy { Object *mObj; int mI; Proxy(Object *obj, int i) : mObj(obj), mI(i) { } int operator[](int j) { return mI * j; } }; Proxy operator[](int i) { return Proxy(this, i); } }; int main() { Object o; std::cout << o[2][3] << std::endl; } 

क्या आपको function , function[x] और function[x][y] बारे में कोई जानकारी मिली है?

पहले function को परिभाषित करने पर ध्यान दें। शायद कुछ घोषणा या परिभाषा जैसी है

SomeClass function;

(क्योंकि आपने कहा था कि यह ऑपरेटर ओवरलोड है, मुझे लगता है कि आप कुछ SomeClass function[16][32]; तरह सरणी में दिलचस्पी नहीं लेंगे SomeClass function[16][32]; )

तो function टाइप करें कुछ SomeClass का एक उदाहरण है फिर कुछ प्रकार के operator[] अधिभार के लिए कुछ SomeClass घोषणा को देखना, जैसे

ReturnType operator[](ParamType);

फिर function[x] में टाइप ReturnType होगा दोबारा operator[] अधिभार के लिए फिर से ReturnType । यदि ऐसी कोई विधि है, तो आप अभिव्यक्ति function[x][y] उपयोग कर सकते हैं

नोट, function(x, y) विपरीत function(x, y) , function[x][y] 2 अलग कॉल हैं न तो कंपाइलर और न ही रनटाइम परमाणुता की गारंटी है। एक अन्य समान उदाहरण है, libc का कहना है printf परमाणु है, जबकि क्रमिक रूप से ओवरलोड किए गए operator<< इन आउटपुट स्ट्रीम में कॉल करता है। जैसे एक बयान

std::cout << "hello" << std::endl;

बहु धागा अनुप्रयोग में समस्या हो सकती है, लेकिन कुछ ऐसा

printf("%s%s", "hello", "\n");

ठीक है।

निष्कर्ष में, हालांकि सी ++ आपके लिए इस तरह की एक शैक्षणिक चीनी की पेशकश करने में सक्षम है, यह कार्यक्रम का अनुशंसित तरीका नहीं है।

 #include<iostream> using namespace std; class Array { private: int *p; public: int length; Array(int size = 0): length(size) { p=new int(length); } int& operator [](const int k) { return p[k]; } }; class Matrix { private: Array *p; public: int r,c; Matrix(int i=0, int j=0):r(i), c(j) { p= new Array[r]; } Array& operator [](const int& i) { return p[i]; } }; /*Driver program*/ int main() { Matrix M1(3,3); /*for checking purpose*/ M1[2][2]=5; } 
 struct test { using array_reference = int(&)[32][32]; array_reference operator [] (std::size_t index) { return m_data[index]; } private: int m_data[32][32][32]; }; 

इस का अपना अपना सरल समाधान मिला

विशेष टेम्पलेट हैंडलर का उपयोग करके कई [] ओवरलोड करना संभव है यह कैसे काम करता है यह दिखाने के लिए:

 #include <iostream> #include <algorithm> #include <numeric> #include <tuple> #include <array> using namespace std; // the number '3' is the number of [] to overload (fixed at compile time) struct TestClass : public SubscriptHandler<TestClass,int,int,3> { // the arguments will be packed in reverse order into a std::array of size 3 // and the last [] will forward them to callSubscript() int callSubscript(array<int,3>& v) { return accumulate(v.begin(),v.end(),0); } }; int main() { TestClass a; cout<<a[3][2][9]; // prints 14 (3+2+9) return 0; } 

और अब SubscriptHandler<ClassType,ArgType,RetType,N> पिछले कोड काम करने के लिए यह केवल दिखाता है कि यह कैसे किया जा सकता है। यह समाधान इष्टतम है और न ही बग रहित (उदाहरण के लिए थ्रेडसेफ नहीं)।

 #include <iostream> #include <algorithm> #include <numeric> #include <tuple> #include <array> using namespace std; template <typename ClassType,typename ArgType,typename RetType, int N> class SubscriptHandler; template<typename ClassType,typename ArgType,typename RetType, int N,int Recursion> class SubscriptHandler_ { ClassType*obj; array<ArgType,N+1> *arr; typedef SubscriptHandler_<ClassType,ArgType,RetType,N,Recursion-1> Subtype; friend class SubscriptHandler_<ClassType,ArgType,RetType,N,Recursion+1>; friend class SubscriptHandler<ClassType,ArgType,RetType,N+1>; public: Subtype operator[](const ArgType& arg){ Subtype s; s.obj = obj; s.arr = arr; arr->at(Recursion)=arg; return s; } }; template<typename ClassType,typename ArgType,typename RetType,int N> class SubscriptHandler_<ClassType,ArgType,RetType,N,0> { ClassType*obj; array<ArgType,N+1> *arr; friend class SubscriptHandler_<ClassType,ArgType,RetType,N,1>; friend class SubscriptHandler<ClassType,ArgType,RetType,N+1>; public: RetType operator[](const ArgType& arg){ arr->at(0) = arg; return obj->callSubscript(*arr); } }; template<typename ClassType,typename ArgType,typename RetType, int N> class SubscriptHandler{ array<ArgType,N> arr; ClassType*ptr; typedef SubscriptHandler_<ClassType,ArgType,RetType,N-1,N-2> Subtype; protected: SubscriptHandler() { ptr=(ClassType*)this; } public: Subtype operator[](const ArgType& arg){ Subtype s; s.arr=&arr; s.obj=ptr; s.arr->at(N-1)=arg; return s; } }; template<typename ClassType,typename ArgType,typename RetType> struct SubscriptHandler<ClassType,ArgType,RetType,1>{ RetType operator[](const ArgType&arg) { array<ArgType,1> arr; arr.at(0)=arg; return ((ClassType*)this)->callSubscript(arr); } }; 
 template<class F> struct indexer_t{ F f; template<class I> std::result_of_t<F const&(I)> operator[](I&&i)const{ return f(std::forward<I>(i))1; } }; template<class F> indexer_t<std::decay_t<F>> as_indexer(F&& f){return {std::forward<F>(f)};} 

यह आपको एक लैम्ब्डा लेता है, और एक इंडेक्सर ( [] समर्थन के साथ) का उत्पादन करने देता है।

मान लीजिए आपके पास एक operator() जो दो तर्कों के रूप में दोनों निर्देशांकों को पारित करने का समर्थन करता है। अब लेखन [][] समर्थन बस है:

 auto operator[](size_t i){ return as_indexer( [i,this](size_t j)->decltype(auto) {return (*this)(i,j);} ); } auto operator[](size_t i)const{ return as_indexer( [i,this](size_t j)->decltype(auto) {return (*this)(i,j);} ); } 

और हो गया। कोई कस्टम वर्ग की आवश्यकता नहीं है।

एक std::vector<std::vector<type*>> , आप कस्टम इनपुट ऑपरेटर का इस्तेमाल करते हुए भीतर के वेक्टर का निर्माण कर सकते हैं जो आपके डेटा पर पुनरावृत्त होता है और प्रत्येक डेटा पर एक पॉइंटर लौटाता है।

उदाहरण के लिए:

 size_t w, h; int* myData = retrieveData(&w, &h); std::vector<std::vector<int*> > data; data.reserve(w); template<typename T> struct myIterator : public std::iterator<std::input_iterator_tag, T*> { myIterator(T* data) : _data(data) {} T* _data; bool operator==(const myIterator& rhs){return rhs.data == data;} bool operator!=(const myIterator& rhs){return rhs.data != data;} T* operator*(){return data;} T* operator->(){return data;} myIterator& operator++(){data = &data[1]; return *this; } }; for (size_t i = 0; i < w; ++i) { data.push_back(std::vector<int*>(myIterator<int>(&myData[i * h]), myIterator<int>(&myData[(i + 1) * h]))); } 

लाइव उदाहरण

यह समाधान आपको एक असली एसटीएल कंटेनर प्रदान करने का फायदा उठाता है, ताकि आप लूप, एसटीएल एल्गोरिदम, और इतने पर विशेष इस्तेमाल कर सकें।

 for (size_t i = 0; i < w; ++i) for (size_t j = 0; j < h; ++j) std::cout << *data[i][j] << std::endl; 

हालांकि, यह पॉइंटर्स के वैक्टर बनाती है, इसलिए यदि आप छोटे डिटेस्ट्रक्चर का उपयोग कर रहे हैं जैसे कि यह एक है तो आप सीधे सरणी के भीतर सामग्री की प्रतिलिपि बना सकते हैं।

नमूना कोड:

 template<class T> class Array2D { public: Array2D(int a, int b) { num1 = (T**)new int [a*sizeof(int*)]; for(int i = 0; i < a; i++) num1[i] = new int [b*sizeof(int)]; for (int i = 0; i < a; i++) { for (int j = 0; j < b; j++) { num1[i][j] = i*j; } } } class Array1D { public: Array1D(int* a):temp(a) {} T& operator[](int a) { return temp[a]; } T* temp; }; T** num1; Array1D operator[] (int a) { return Array1D(num1[a]); } }; int _tmain(int argc, _TCHAR* argv[]) { Array2D<int> arr(20, 30); std::cout << arr[2][3]; getchar(); return 0; } 

वेक्टर <वेक्टर <टी>> या टी ** केवल तब ही आवश्यक होता है जब आपके पास चर लंबाई की पंक्तियां हो और जिस तरह से स्मृति उपयोग / आवंटन के मामले में भी अक्षम है यदि आपको आयताकार सरणी की आवश्यकता होती है तो इसके बजाय कुछ गणित करने पर विचार करें! देखें () विधि:

 template<typename T > class array2d { protected: std::vector< T > _dataStore; size_t _sx; public: array2d(size_t sx, size_t sy = 1): _sx(sx), _dataStore(sx*sy) {} T& at( size_t x, size_t y ) { return _dataStore[ x+y*sx]; } const T& at( size_t x, size_t y ) const { return _dataStore[ x+y*sx]; } const T& get( size_t x, size_t y ) const { return at(x,y); } void set( size_t x, size_t y, const T& newValue ) { at(x,y) = newValue; } }; 

सी ++ 11 और मानक पुस्तकालय का उपयोग करके आप कोड की एक पंक्ति में एक बहुत ही अच्छी दो-आयामी सरणी बना सकते हैं:

 std::array<std::array<int, columnCount>, rowCount> myMatrix {0}; std::array<std::array<std::string, columnCount>, rowCount> myStringMatrix; std::array<std::array<Widget, columnCount>, rowCount> myWidgetMatrix; 

इनर मैट्रिक्स का निर्णय लेने से पंक्तियों का प्रतिनिधित्व करता है, आप मैट्रिक्स को मेरे मैट्रिक्स myMatrix[y][x] वाक्यविन्यास के साथ एक्सेस करते हैं:

 myMatrix[0][0] = 1; myMatrix[0][3] = 2; myMatrix[3][4] = 3; std::cout << myMatrix[3][4]; // outputs 3 myStringMatrix[2][4] = "foo"; myWidgetMatrix[1][5].doTheStuff(); 

और आप आउटपुट for लिए लेकर- उपयोग कर सकते हैं:

 for (const auto &row : myMatrix) { for (const auto &elem : row) { std::cout << elem << " "; } std::cout << std::endl; } 

(इनर array का निर्णय लेने से पता चलता है कि कॉलम एक foo[x][y] वाक्यविन्यास के लिए अनुमति देते हैं, लेकिन आप आउटपुट को प्रदर्शित करने के for(;;) छोरों के लिए छद्म का उपयोग करने की आवश्यकता होती है।)