इस तरह के vector
या किसी अन्य लागू (म्यूट इनपुट इनपुट) प्रकार की कस्टम वस्तुओं की श्रेणी को X
विभिन्न तरीकों का उपयोग करके प्राप्त किया जा सकता है, विशेष रूप से मानक पुस्तकालय एल्गोरिदम जैसे उपयोग
चूंकि अधिकांश तकनीकें, X
तत्वों के सापेक्ष आदेश प्राप्त करने के लिए , पहले से ही पोस्ट की जा चुकी हैं, मैं विभिन्न दृष्टिकोणों का उपयोग करने के लिए "क्यों" और "कब" पर कुछ नोटों से शुरू करूंगा।
"सर्वश्रेष्ठ" दृष्टिकोण विभिन्न कारकों पर निर्भर करेगा:
- क्या
X
वस्तुओं की श्रेणी को एक सामान्य या एक दुर्लभ कार्य है (क्या इस तरह की श्रेणियों को कार्यक्रम में या पुस्तकालय उपयोगकर्ताओं द्वारा अलग-अलग स्थानों पर छांटा जा सकता है)?
- क्या आवश्यक छंटाई "प्राकृतिक" (अपेक्षित) है या क्या कई तरीके हैं जिनकी तुलना स्वयं की जा सकती है?
- क्या प्रदर्शन एक मुद्दा है या
X
वस्तुओं की श्रेणियों को छांटना मूर्खतापूर्ण होना चाहिए?
यदि छँटाई की सीमा X
एक सामान्य कार्य है और प्राप्त छँटाई की उम्मीद की जानी है (यानी X
सिर्फ एक मौलिक मूल्य लपेटता है) तो शायद ओवरलोडिंग के लिए जाता है operator<
क्योंकि यह बिना किसी फ़ज़ल के छँटाई करने में सक्षम बनाता है (जैसे सही ढंग से उचित तुलनित्रों को पास करना) और बार-बार पैदावार की उम्मीद करना परिणाम है।
यदि छंटनी एक सामान्य कार्य है या विभिन्न संदर्भों में आवश्यक होने की संभावना है, लेकिन कई मापदंड हैं जिनका उपयोग X
वस्तुओं को क्रमबद्ध करने के लिए किया जा सकता है , मैं फ़ंकर्स ( operator()
कस्टम कक्षाओं के अतिभारित कार्यों) या फ़ंक्शन पॉइंटर्स (यानी एक फ़नकार / फ़ंक्शन) के लिए जाऊंगा लेक्सिकल ऑर्डरिंग के लिए और प्राकृतिक ऑर्डरिंग के लिए एक और)।
यदि X
अन्य प्रकारों की छंटाई की गई सीमाएँ असामान्य या असंभाव्य हैं, तो मैं किसी भी नामस्थान को अधिक कार्यों या प्रकारों के साथ अव्यवस्थित करने के बजाय लंबोदा का उपयोग करता हूं।
यह विशेष रूप से सच है अगर छंटाई किसी तरह "स्पष्ट" या "प्राकृतिक" नहीं है। ऑर्डर देने के पीछे तर्क को आप आसानी से देख सकते हैं operator<
, जो पहली बार में अस्पष्ट है जबकि लैम्बडा को देखते हैं और आपको यह देखने के लिए परिभाषा को देखना होगा कि ऑर्डर करने वाले लॉजिक को क्या लागू किया जाएगा।
हालाँकि, ध्यान दें कि एक एकल operator<
परिभाषा विफलता का एक बिंदु है जबकि कई लंबो विफलता के कई बिंदु हैं और एक अधिक सावधानी की आवश्यकता होती है।
यदि operator<
सॉर्टिंग की परिभाषा उपलब्ध नहीं है, जहां सॉर्ट किया गया है / सॉर्ट टेम्पलेट संकलित किया गया है, तो कंपाइलर को ऑर्डर की तर्क को टालने के बजाय, ऑब्जेक्ट की तुलना करते समय एक फ़ंक्शन कॉल करने के लिए मजबूर किया जा सकता है जो एक गंभीर खामी हो सकती है (कम से कम जब लिंक समय अनुकूलन / कोड पीढ़ी लागू नहीं होती है)।
class X
मानक पुस्तकालय छँटाई एल्गोरिदम का उपयोग करने के लिए तुलनात्मकता प्राप्त करने के तरीके
चलो std::vector<X> vec_X;
औरstd::vector<Y> vec_Y;
1. अधिभार T::operator<(T)
या operator<(T, T)
मानक पुस्तकालय टेम्पलेट्स का उपयोग करें जो एक तुलना फ़ंक्शन की अपेक्षा नहीं करते हैं।
या तो ओवरलोड सदस्य operator<
:
struct X {
int i{};
bool operator<(X const &r) const { return i < r.i; }
};
// ...
std::sort(vec_X.begin(), vec_X.end());
या मुफ्त operator<
:
struct Y {
int j{};
};
bool operator<(Y const &l, Y const &r) { return l.j < r.j; }
// ...
std::sort(vec_Y.begin(), vec_Y.end());
2. फंक्शन पॉइंटर का उपयोग कस्टम फंक्शन के साथ फंक्शन पैरामीटर को सॉर्ट करने के लिए करें।
struct X {
int i{};
};
bool X_less(X const &l, X const &r) { return l.i < r.i; }
// ...
std::sort(vec_X.begin(), vec_X.end(), &X_less);
3. bool operator()(T, T)
एक कस्टम प्रकार के लिए एक अधिभार बनाएं जो तुलना फ़नकार के रूप में पारित किया जा सकता है।
struct X {
int i{};
int j{};
};
struct less_X_i
{
bool operator()(X const &l, X const &r) const { return l.i < r.i; }
};
struct less_X_j
{
bool operator()(X const &l, X const &r) const { return l.j < r.j; }
};
// sort by i
std::sort(vec_X.begin(), vec_X.end(), less_X_i{});
// or sort by j
std::sort(vec_X.begin(), vec_X.end(), less_X_j{});
उन फ़ंक्शन ऑब्जेक्ट परिभाषाओं को C ++ 11 और टेम्पलेट्स का उपयोग करके थोड़ा और सामान्य लिखा जा सकता है:
struct less_i
{
template<class T, class U>
bool operator()(T&& l, U&& r) const { return std::forward<T>(l).i < std::forward<U>(r).i; }
};
जिसका उपयोग सदस्य i
समर्थन के साथ किसी भी प्रकार को सॉर्ट करने के लिए किया जा सकता है <
।
4. अनाम अनाम क्लोजर (लैम्ब्डा) को सॉर्टिंग फ़ंक्शंस के तुलना पैरामीटर के रूप में पास करें।
struct X {
int i{}, j{};
};
std::sort(vec_X.begin(), vec_X.end(), [](X const &l, X const &r) { return l.i < r.i; });
जहाँ C ++ 14 और भी अधिक सामान्य लंबोदर अभिव्यक्ति को सक्षम बनाता है:
std::sort(a.begin(), a.end(), [](auto && l, auto && r) { return l.i < r.i; });
जिसे मैक्रो में लपेटा जा सकता है
#define COMPARATOR(code) [](auto && l, auto && r) -> bool { return code ; }
साधारण तुलनित्र निर्माण को काफी सुचारू बनाना:
// sort by i
std::sort(v.begin(), v.end(), COMPARATOR(l.i < r.i));
// sort by j
std::sort(v.begin(), v.end(), COMPARATOR(l.j < r.j));