Search code examples
c++friendlist-initialization

Why doesn't this friend function allow brace-init-list but the static one does?


Basically this code won't compile

struct M
{
    static void staticF(M m) {}
    friend void friendF(M m) {}
};

int main()
{
    M::staticF({}); //< okay
    M m;
    friendF(m); //< okay
    friendF({}); //< error: doesn't the compiler allow this?
}

The compiler says that friendF "is not declared in the scope".

Try the code: https://godbolt.org/z/8Mq664


Solution

  • The problem is not the {}, but as the compiler says: The function is not declared in the scope where you try to call it. Add a declaration:

    struct M
    {
        static void staticF(M m) {}
        friend void friendF(M m) {}
    };
    
    void friendF(M m);
    
    int main()
    {
        M::staticF({}); //< okay
        M m;
        friendF(m); //< okay
        friendF({}); //< okay
    }
    

    The reason friendF(m); also worked without the declaration is Argument Dependent Lookup (ADL). In a nutshell: The compiler looks for friendF based on where its parameter is declared.

    Note the typically the friend declaration is only the declaration and the definition is usually provided outside of the class:

    struct M
    {
        static void staticF(M m) {}
        void friendF(M m);
    };
    
    void friendF(M m) {}
    

    If the function is only used in the scope of the class then it can be a private member.