Для первого требуется определение container
, так как вы выполняете операцию копирования. Если вы определите конструктор iter
после определения container
, все будет в порядке. Итак:
struct container;
struct iter {
container &c;
int *p;
iter(container &c);
};
struct container {
int x;
int &value() { return x; }
iter begin() { return iter(*this); }
};
iter::iter(container &c) : c(c), p(&c.value()) {}
int main() {
container c;
c.begin();
return 0;
}
Второй пример работает, потому что нет класса, пока вы не создадите его в своей функции main
. К этому времени все типы определены. Попробуйте переместить любое определение шаблона iter
или container
после основного, и вы получите ошибку.
Третий пример - это специализация для int
или около того. Это должно скомпилироваться, потому что параметр шаблона для iter
не используется. Синтаксис специализации немного отключен. Тем не менее, нет подходящего конструктора, поэтому вы получите мусор только для x
. Более того, итераторы хорошо моделируются указателями. Передача значения this
не сильно поможет. Итераторы обычно требуются для последовательности, а не для отдельного объекта. Однако ничто не может помешать вам построить его.
И вам не нужно ;
после тела функции.