मैं अनुक्रमों के कार्यात्मक शैली के निर्माण के लिए कुछ कोड लिखने की कोशिश कर रहा था। मैंने एक फ़ंक्शन, range(a, b)
लिखा है, जो एक ऑब्जेक्ट देता है जिसे आप नंबर, ए + 1, ..., बी -1 के माध्यम से जाने के लिए फिर से शुरू कर सकते हैं। फिर मैंने एक और फ़ंक्शन लिखा, map(f, t)
, जो रिटर्न एक अन्य पुनरावर्तनीय वस्तु जहां अनुक्रम में प्रत्येक तत्व f
को पुनरावृत्त ऑब्जेक्ट t
के संबंधित तत्व के साथ कॉल करने का परिणाम है।जीसीसी मेरे कस्टम इटरेटर का उपयोग कर इस सी ++ 11 फोरैच लूप को ऑप्टिमाइज़ क्यों करता है?
यह अपेक्षा करता है कि यदि मैं -O1
या उससे कम का उपयोग कर संकलित करता हूं; -O2
या उच्चतम के साथ, मेरा फ़ोरैच लूप (नीचे main
में) पूरी तरह से अनुकूलित हो जाता है और कुछ भी मुद्रित नहीं होता है। ऐसा क्यों होता है, मैंने क्या गलत किया है?
template<typename T>
struct _range {
T a;
T b;
_range(T a, T b):
a(a),
b(b)
{
}
struct iterator {
T it;
iterator(T it):
it(it)
{
}
bool operator!=(const iterator &other) const
{
return it != other.it;
}
void operator++()
{
++it;
}
T operator*() const
{
return it;
}
};
iterator begin() const
{
return iterator(a);
}
iterator end() const
{
return iterator(b);
}
};
template<typename T>
_range<T> range(const T a, const T b)
{
return _range<T>(a, b);
}
template<typename F, typename T>
struct _map {
const F &f;
const T &t;
_map(const F &f, const T &t):
f(f),
t(t)
{
}
struct iterator {
const F &f;
typename T::iterator it;
iterator(const F &f, typename T::iterator it):
f(f),
it(it)
{
}
bool operator!=(const iterator &other) const
{
return it != other.it;
}
void operator++()
{
++it;
}
int operator*() const
{
return f(*it);
}
};
iterator begin() const
{
return iterator(f, t.begin());
}
iterator end() const
{
return iterator(f, t.end());
}
};
template<typename F, typename T>
_map<F, T> map(const F &f, const T &t)
{
return _map<F, T>(f, t);
}
#include <algorithm>
#include <cstdio>
int main(int argc, char *argv[])
{
for (int i: map([] (int x) { return 3 * x; }, range(-4, 5)))
printf("%d\n", i);
return 0;
}
शायद एक बग? क्लैंग ++ के साथ, यह ओ 1 और ओ 2 अनुकूलन स्तर दोनों के साथ ठीक काम करता है। –
'_map' को अपने सदस्यों को कॉन्स रेफरी संग्रहीत करने के बजाय मूल्य के आधार पर स्टोर करने का प्रयास करें। (मुझे संदेह है कि आपकी 'रेंज' ऑब्जेक्ट को उम्मीद से पहले नष्ट किया जा रहा है।) – ildjarn
मेरा मानना है कि @ildjarn इसे सही मिला: अस्थायी को तब तक जीने के लिए मजबूर होना पड़ता है जब तक निरंतर संदर्भ जीवित नहीं है। संदर्भ यह है कि यह 'मानचित्र' के निर्माता का तर्क है। जब कन्स्ट्रक्टर लौटाता है, तो संदर्भ दायरे से बाहर हो जाता है और अस्थायी नष्ट हो जाता है। –