嵌套 class "does not name a type"
Nested class "does not name a type"
我收到以下错误:
main.cpp:18:5: error: 'Iterator' does not name a type
18 | Iterator begin() {
| ^~~~~~~~
使用此代码:
#include <iostream>
#include <iostream>
#include <memory>
#include <fstream>
#include <filesystem>
using namespace std;
class Numbers {
private:
int current;
int end;
public:
Numbers(int end) : current(0), end(end) {}
Iterator begin() {
return Iterator(this);
}
bool operator==(const Numbers& other) const {
return current == other.current && end == other.end;
}
bool operator!=(const Numbers& other) const {
return !(other == *this);
}
class Iterator {
private:
Numbers* range;
public:
using value_type = int;
using difference_type = ptrdiff_t;
using pointer = int*;
using reference = int&;
using iterator_category = input_iterator_tag;
Iterator(Numbers* range) : range(range) {}
int operator*() const {
return range->current;
}
int* operator->() const {
return &range->current;
}
bool operator==(const Iterator& other) const {
return other.range == range;
}
bool operator!=(const Iterator& other) const {
return !(*this == other);
}
Iterator& operator++() {
range->current++;
return *this;
}
};
};
事实证明,将 begin
函数 移动到 嵌套的 Iterator
class 下可以编译。
但这很奇怪 - 嵌套的 class 是否遵循与任何其他成员相同的访问规则,这意味着不需要前向引用?
我在网站上搜索了关于这个确切问题的其他问题,似乎没有找到答案。
从评论到问题
Also - I have no problem calling member function f in member function
q where f is defined after q. Can you explain why the latter example
is different than the situation described in this question?
根据 C++ 20 标准(11.4 Class 个成员)
6 A complete-class context of a class is a
> (6.1) — function body (9.5.1),
(6.2) — default argument (9.3.3.6),
(6.3) — noexcept-specifier (14.5), or
(6.4) — default member initializer
within the member-specification of the class
因此在完整的 class 上下文中,函数 f
的名称在函数 q
.
的主体中可见
然而,内部 class 是在完整的 class 上下文之外声明的。所以根据 C++ 20 Standard (6.5.1 Unqualified name lookup)
7 A name used in the definition of a class X23 outside of a
complete-class context (11.4) of X shall be declared in one of the
following ways:
> (7.1) — before its use in class X or be a member of a base class of X
(11.8), or
...
所以内部 class Iterator
的名称必须在用作 return 类型的成员函数之前声明。
您可以使用占位符 auto
作为 return 类型来代替名称 Iterator。
auto begin() {
return Iterator(this);
}
我收到以下错误:
main.cpp:18:5: error: 'Iterator' does not name a type
18 | Iterator begin() {
| ^~~~~~~~
使用此代码:
#include <iostream>
#include <iostream>
#include <memory>
#include <fstream>
#include <filesystem>
using namespace std;
class Numbers {
private:
int current;
int end;
public:
Numbers(int end) : current(0), end(end) {}
Iterator begin() {
return Iterator(this);
}
bool operator==(const Numbers& other) const {
return current == other.current && end == other.end;
}
bool operator!=(const Numbers& other) const {
return !(other == *this);
}
class Iterator {
private:
Numbers* range;
public:
using value_type = int;
using difference_type = ptrdiff_t;
using pointer = int*;
using reference = int&;
using iterator_category = input_iterator_tag;
Iterator(Numbers* range) : range(range) {}
int operator*() const {
return range->current;
}
int* operator->() const {
return &range->current;
}
bool operator==(const Iterator& other) const {
return other.range == range;
}
bool operator!=(const Iterator& other) const {
return !(*this == other);
}
Iterator& operator++() {
range->current++;
return *this;
}
};
};
事实证明,将 begin
函数 移动到 嵌套的 Iterator
class 下可以编译。
但这很奇怪 - 嵌套的 class 是否遵循与任何其他成员相同的访问规则,这意味着不需要前向引用?
我在网站上搜索了关于这个确切问题的其他问题,似乎没有找到答案。
从评论到问题
Also - I have no problem calling member function f in member function q where f is defined after q. Can you explain why the latter example is different than the situation described in this question?
根据 C++ 20 标准(11.4 Class 个成员)
6 A complete-class context of a class is a
> (6.1) — function body (9.5.1),
(6.2) — default argument (9.3.3.6),
(6.3) — noexcept-specifier (14.5), or
(6.4) — default member initializer
within the member-specification of the class
因此在完整的 class 上下文中,函数 f
的名称在函数 q
.
然而,内部 class 是在完整的 class 上下文之外声明的。所以根据 C++ 20 Standard (6.5.1 Unqualified name lookup)
7 A name used in the definition of a class X23 outside of a complete-class context (11.4) of X shall be declared in one of the following ways:
> (7.1) — before its use in class X or be a member of a base class of X (11.8), or ...
所以内部 class Iterator
的名称必须在用作 return 类型的成员函数之前声明。
您可以使用占位符 auto
作为 return 类型来代替名称 Iterator。
auto begin() {
return Iterator(this);
}