Search code examples
c++standardsname-lookup

Declaration after use


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 of X shall be declared ... before its use in class X or be a member of a base class of X....

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.


Solution

  • 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