在 returns 模板 class 的全局命名空间中声明友元函数

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

我在命名空间中声明了一个函数,当它被定义为友元时,会抛出编译器错误。

#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();
};

编译失败,出现错误

'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

然而,如果我从 ::Example::GetNames() 中删除全局命名空间标识符 ::,它将顺利编译。

由于命名空间嵌套,我需要从全局命名空间开始,我该如何处理这个问题?

编译器没有按照您的预期评估您的友元声明。相反,编译器读取以下内容:

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

它认为你想在 vector class.
中的命名空间 Example 内声明函数 GetNames 这就是为什么当您删除 :: 时,编译器可以查找命名空间 Example 本身并在全局命名空间中找到它。

您想告诉编译器有一个名为 Example 的全局命名空间,而是在函数声明两边加上括号:

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

现在,这会根据您的需要进行评估。