the order of member variable in class template

447 views Asked by At

I've defined a class template and a function,

template <typename F> class Base {
    public:
        Base(F ff): f(ff) {}
        template <typename... Ps> auto operator() (Ps... ps) const -> decltype(f(ps...)) { return f(ps...); }
    private:
        // f is a pointer to function
        F* f;   
};

int f(int i, int j) 
{
    return i + j;
}

int main()
{
    using f_type = remove_reference<decltype(f)>::type;
    Base<f_type> b{f};
    b(2, 5); // [Error] no match for call to '(Base<int(int, int)>) (int, int)'
}

the labeled error was reported. But when I changed the order of member variable of class Base, like:

template <typename F> class Base {
    private:
        // f is a pointer to function
        F* f;   
    public:
        Base(F ff): f(ff) {}
        template <typename... Ps> auto operator() (Ps... ps) const -> decltype(f(ps...)) { return f(ps...); }
};

It can compile.

What's the reason of these two different results? Thank you for your time!

1

There are 1 answers

4
Dietmar Kühl On BEST ANSWER

Declarations are introduced in C++ in the order they are seen in the source. The notable exception where things are different are the bodies of member functions: when member functions are defined within the class declaration, the definition (but not its declaration) behaves as if the function is defined immediately after the class definition.

Since the rules about the location of member definitions does not apply to the declarations names used in the member function declaration need to be declared at this point. Changing the location of the member provides the necessary declaration.