CommanderBubble
CommanderBubble

Reputation: 333

declaring a friend function in the global namespace that returns a template class

i have a function declared in a namespace, that when it is defined as a friend, throws a compiler error.

#include <string>
#include <vector>

namespace Example
{
    std::vector<std::string> GetNames();
}

class MyClass
{
    public:
        MyClass() : 
                name("data")
        {}

    private:
        std::string name;

    friend std::vector<std::string> ::Example::GetNames();
};

this fails to compile with the error

'Example' in 'class std::vectorstd::__cxx11::basic_string<char >' does not name a type friend std::vectorstd::string ::Example::GetNames(); ^~~~~~~ main.cpp:25:2: error: expected ';' after class definition

yet if i remove the global namespace identifier, :: from ::Example::GetNames(), it will compile happily.

how do i deal with this issue when i need to start at the global namespace due to nested namespaces?

Upvotes: 0

Views: 183

Answers (1)

FMeinicke
FMeinicke

Reputation: 658

The compiler doesn't evaluate your friend declaration as you intended it to. Instead, the compiler reads the following:

    friend std::vector<std::string>::Example::GetNames();

It thinks that you want to declare the function GetNames that is within a namespace Example inside the vector class.
That's why when you remove the :: the compiler can lookup the namespace Example itself and finds it in the global namespace.

What you want to do instead to tell the compiler that there is a global namespace called Example is to put parentheses around the function declaration:

    friend std::vector<std::string> (::Example::GetNames)();

Now, this gets evaluated as you want to.

Upvotes: 8

Related Questions