The draft C++20 standard N4861 sect. 6.5.1(7) reads:
A name used in the definition of a class
X
outside of a complete-class context ofX
shall be declared ... before its use in classX
or be a member of a base class ofX
....
So why does the following compile?
#include <iostream>
struct X {
X(const int i_) : i(i_) {}
int f() const { return 3*g(); }
int g() const { return 2*i; }
const int i;
};
int main()
{
const X x{7};
std::cout << x.f() << "\n";
}
I mean, of course, it should indeed compile, and does, and the output is 42
just as one would expect; but I do not understand the standard's phrasing. The standard says, "before its use," but in the example, isn't g()
declared after its use? And i
, too.
The key part to the paragraph you are quoting is
outside of a complete-class context
Inside a member function body, you are in a complete-class context. This means the rule does not apply.
The full definition for a complete-class contect can be found in [class.mem.general]/7:
A complete-class context of a class (template) is a
- function body ([dcl.fct.def.general]),
- default argument ([dcl.fct.default]),
- default template argument ([temp.param]), noexcept-specifier ([except.spec]), or
- default member initializer