किसी के लिए जो कि Cigien का std::views::iota
जवाब पसंद करता है, लेकिन C ++ 20 या इसके बाद के संस्करण में काम नहीं कर रहा है, यह std::views::iota
संगत के सरलीकृत और हल्के लागू करने के लिए सीधा हैc ++ 11 या ऊपर।
इसकी आवश्यकता है:
- एक मूल " LegacyInputIterator " प्रकार (कुछ ऐसा जो परिभाषित करता है
operator++
और operator*
) जो एक अभिन्न मूल्य (जैसे एक int
) को लपेटता है
- कुछ "रेंज" जैसी श्रेणी जिसके पास है
begin()
और end()
जो उपरोक्त पुनरावृत्तियों को लौटाता है। यह इसे रेंज-आधारित for
लूप में काम करने की अनुमति देगा
इसका एक सरलीकृत संस्करण हो सकता है:
#include <iterator>
class counting_iterator
{
public:
using iterator_category = std::input_iterator_tag;
using value_type = int;
using reference = int;
using pointer = int*;
using difference_type = std::ptrdiff_t;
constexpr explicit counting_iterator(int x) : m_value{x}{}
constexpr counting_iterator(const counting_iterator&) = default;
constexpr counting_iterator& operator=(const counting_iterator&) = default;
constexpr reference operator*() const { return m_value; }
constexpr pointer operator->() const { return &m_value; }
constexpr counting_iterator& operator++() {
m_value++;
return (*this);
}
constexpr counting_iterator operator++(int) {
const auto copy = (*this);
++(*this);
return copy;
}
constexpr bool operator==(const counting_iterator& other) const noexcept {
return m_value == other.m_value;
}
constexpr bool operator!=(const counting_iterator& other) const noexcept {
return m_value != other.m_value;
}
private:
int m_value;
};
struct iota_range
{
int first;
int last;
constexpr counting_iterator begin() const { return counting_iterator{first}; }
constexpr counting_iterator end() const { return counting_iterator{last}; }
};
constexpr iota_range iota(int first, int last)
{
return iota_range{first, last};
}
मैंने ऊपर constexpr
जहां यह समर्थित है, के साथ परिभाषित किया है, लेकिन C ++ 11/14 जैसे C ++ के पुराने संस्करणों के लिए, आपको constexpr
यह हटाने की आवश्यकता हो सकती है कि ऐसा करने के लिए उन संस्करणों में कानूनी नहीं है।
उपरोक्त बॉयलरप्लेट प्री-सी ++ 20 में काम करने के लिए निम्नलिखित कोड को सक्षम करता है:
for (int const i : iota(0, 10))
{
std::cout << i << " ";
i = 42;
}
जो अनुकूलित होने पर C ++ 20 समाधान और क्लासिक- लूप समाधान के समान विधानसभा उत्पन्न करेगा ।std::views::iota
for
यह किसी भी C ++ 11-कंपाइलर कंपाइलर (जैसे कंपाइलर gcc-4.9.4
) के साथ काम करता है और फिर भी एक बेसिक- क्लोजर समकक्ष के लिए लगभग समान असेंबली का उत्पादन करता for
है।
नोट:iota
सहायक समारोह सिर्फ सी ++ 20 के साथ सुविधा समता के लिए है std::views::iota
समाधान; लेकिन वास्तविक रूप से, आप iota_range{...}
कॉल करने के बजाय सीधे निर्माण भी कर सकते हैं iota(...)
। यदि उपयोगकर्ता भविष्य में C ++ 20 पर स्विच करना चाहता है तो पूर्व केवल एक आसान अपग्रेड पथ प्रस्तुत करता है।