[C++] Q_FOREACH (= foreach) 매크로는 어떻게 작동하며 왜 그렇게 복잡합니까?


Answers

Question

Qt에는 매크로 ( Q_FOREACH )를 사용하여 구현되는 foreach 루프가 있습니다. 컴파일러에 따라 다른 구현이 있습니다.

GCC 의 정의는 다음과 같습니다.

#define Q_FOREACH(variable, container)                                \
for (QForeachContainer<__typeof__(container)> _container_(container); \
     !_container_.brk && _container_.i != _container_.e;              \
     __extension__  ({ ++_container_.brk; ++_container_.i; }))        \
    for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))

... 다음과 같이 정의 된 도우미 클래스 QForeachContainer 사용 :

template <typename T>
class QForeachContainer {
public:
    inline QForeachContainer(const T& t) : c(t), brk(0), i(c.begin()), e(c.end()) { }
    const T c;
    int brk;
    typename T::const_iterator i, e;
};

Q_FOREACH 매크로의 컨테이너는 T::const_iterator 유형, T.begin()T.end() 메소드를 제공 Q_FOREACH 클래스 T T.begin() 합니다. 모든 STL 컨테이너뿐만 아니라 대부분의 Qt도 마찬가지입니다. QList , QVector , QMap , QHash 등의 컨테이너

내 질문은 지금 : 이 매크로는 어떻게 작동합니까?

한 가지는 정말 이상하게 보입니다. 변수는 매크로 정의에 한 번만 나타납니다. 예를 들어, foreach(QString item, list)QString item = 가지고 있습니다. 그러나 나중에 언제든지 item 을 쓸 수는 없습니다 ... 어떻게 변수 item 을 각 단계에서 변경할 수 있습니까?

MS VC ++ 컴파일러에 대한 Q_FOREACH 의 다음 정의가 더욱 혼란 스럽습니다.

#define Q_FOREACH(variable,container)                                                         \
if(0){}else                                                                                     \
for (const QForeachContainerBase &_container_ = qForeachContainerNew(container);                \
     qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->condition();       \
     ++qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->i)               \
    for (variable = *qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->i; \
         qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->brk;           \
         --qForeachContainer(&_container_, true ? 0 : qForeachPointer(container))->brk)

true : 0 ? ... true : 0 ? ... ? 항상 0 평가되지 않습니까? 이전에 조건이 있더라도 함수 호출 qForeachPointer(container) 실행 ? 사실이다?

그리고 왜 for-loops가 두 개 필요합니까?

누군가가 나를 위해 조금 더 명확하게 만들 수 있다면 멋질 것입니다!