स्वीकृत उत्तर की पहली (अच्छी तरह से मतदान) टिप्पणी मौजूदा एसटीडी संचालन के लिए एक लापता ऑपरेटर के बारे में शिकायत करती है।
एक तरफ, मैं मानक पुस्तकालय में ऐसे ऑपरेटरों की कमी को समझता हूं। दूसरी ओर, उन्हें (व्यक्तिगत आनंद के लिए) अगर चाहें तो जोड़ना आसान है। मैंने ओवरलोड किया
operator *()
सेट के प्रतिच्छेदन के लिए
operator +()
सेटों के मिलन के लिए।
नमूना test-set-ops.cc
:
#include <algorithm>
#include <iterator>
#include <set>
template <class T, class CMP = std::less<T>, class ALLOC = std::allocator<T> >
std::set<T, CMP, ALLOC> operator * (
const std::set<T, CMP, ALLOC> &s1, const std::set<T, CMP, ALLOC> &s2)
{
std::set<T, CMP, ALLOC> s;
std::set_intersection(s1.begin(), s1.end(), s2.begin(), s2.end(),
std::inserter(s, s.begin()));
return s;
}
template <class T, class CMP = std::less<T>, class ALLOC = std::allocator<T> >
std::set<T, CMP, ALLOC> operator + (
const std::set<T, CMP, ALLOC> &s1, const std::set<T, CMP, ALLOC> &s2)
{
std::set<T, CMP, ALLOC> s;
std::set_union(s1.begin(), s1.end(), s2.begin(), s2.end(),
std::inserter(s, s.begin()));
return s;
}
#include <iostream>
using namespace std;
template <class T>
ostream& operator << (ostream &out, const set<T> &values)
{
const char *sep = " ";
for (const T &value : values) {
out << sep << value; sep = ", ";
}
return out;
}
int main()
{
set<int> s1 { 1, 2, 3, 4 };
cout << "s1: {" << s1 << " }" << endl;
set<int> s2 { 0, 1, 3, 6 };
cout << "s2: {" << s2 << " }" << endl;
cout << "I: {" << s1 * s2 << " }" << endl;
cout << "U: {" << s1 + s2 << " }" << endl;
return 0;
}
संकलित और परीक्षण किया गया:
$ g++ -std=c++11 -o test-set-ops test-set-ops.cc
$ ./test-set-ops
s1: { 1, 2, 3, 4 }
s2: { 0, 1, 3, 6 }
I: { 1, 3 }
U: { 0, 1, 2, 3, 4, 6 }
$
मुझे जो पसंद नहीं है वह ऑपरेटरों में रिटर्न वैल्यू की कॉपी है। हो सकता है, यह चाल असाइनमेंट का उपयोग करके हल किया जा सकता है लेकिन यह अभी भी मेरे कौशल से परे है।
इन "नए फैंसी" चाल शब्दार्थों के बारे में मेरे सीमित ज्ञान के कारण, मैं ऑपरेटर रिटर्न के बारे में चिंतित था जो कि रिटर्न सेट की प्रतियां पैदा कर सकता था। ओलाफ डाइटशे ने बताया कि ये चिंताएँ अनावश्यक हैं क्योंकि std::set
पहले से ही मूव कंस्ट्रक्टर / असाइनमेंट से लैस है।
हालांकि मुझे उस पर विश्वास था, मैं सोच रहा था कि इसे कैसे चेक किया जाए ("आत्म-आश्वस्त" जैसी चीज़ के लिए)। दरअसल, यह काफी आसान है। जैसा कि टेम्पलेट्स को स्रोत कोड में प्रदान करना होता है, आप बस डिबगर के माध्यम से कदम बढ़ा सकते हैं। इस प्रकार, मैं कम से एक को तोड़ने बिंदु सही रखा return s;
की operator *()
और एकल कदम जो मुझे में तुरंत लीडेड साथ रवाना हुएstd::set::set(_myt&& _Right)
: एट देखा - चाल निर्माता। धन्यवाद, ओलाफ, (मेरे) ज्ञानोदय के लिए।
पूर्णता के लिए, मैंने इसी असाइनमेंट ऑपरेटरों को भी लागू किया
operator *=()
सेट के "विनाशकारी" चौराहे के लिए
operator +=()
सेट के "विनाशकारी" संघ के लिए।
नमूना test-set-assign-ops.cc
:
#include <iterator>
#include <set>
template <class T, class CMP = std::less<T>, class ALLOC = std::allocator<T> >
std::set<T, CMP, ALLOC>& operator *= (
std::set<T, CMP, ALLOC> &s1, const std::set<T, CMP, ALLOC> &s2)
{
auto iter1 = s1.begin();
for (auto iter2 = s2.begin(); iter1 != s1.end() && iter2 != s2.end();) {
if (*iter1 < *iter2) iter1 = s1.erase(iter1);
else {
if (!(*iter2 < *iter1)) ++iter1;
++iter2;
}
}
while (iter1 != s1.end()) iter1 = s1.erase(iter1);
return s1;
}
template <class T, class CMP = std::less<T>, class ALLOC = std::allocator<T> >
std::set<T, CMP, ALLOC>& operator += (
std::set<T, CMP, ALLOC> &s1, const std::set<T, CMP, ALLOC> &s2)
{
s1.insert(s2.begin(), s2.end());
return s1;
}
#include <iostream>
using namespace std;
template <class T>
ostream& operator << (ostream &out, const set<T> &values)
{
const char *sep = " ";
for (const T &value : values) {
out << sep << value; sep = ", ";
}
return out;
}
int main()
{
set<int> s1 { 1, 2, 3, 4 };
cout << "s1: {" << s1 << " }" << endl;
set<int> s2 { 0, 1, 3, 6 };
cout << "s2: {" << s2 << " }" << endl;
set<int> s1I = s1;
s1I *= s2;
cout << "s1I: {" << s1I << " }" << endl;
set<int> s2I = s2;
s2I *= s1;
cout << "s2I: {" << s2I << " }" << endl;
set<int> s1U = s1;
s1U += s2;
cout << "s1U: {" << s1U << " }" << endl;
set<int> s2U = s2;
s2U += s1;
cout << "s2U: {" << s2U << " }" << endl;
return 0;
}
संकलित और परीक्षण किया गया:
$ g++ -std=c++11 -o test-set-assign-ops test-set-assign-ops.cc
$ ./test-set-assign-ops
s1: { 1, 2, 3, 4 }
s2: { 0, 1, 3, 6 }
s1I: { 1, 3 }
s2I: { 1, 3 }
s1U: { 0, 1, 2, 3, 4, 6 }
s2U: { 0, 1, 2, 3, 4, 6 }
$