【问题标题】:declaring a friend function in the global namespace that returns a template class在全局命名空间中声明一个返回模板类的友元函数
【发布时间】:2020-09-16 12:15:56
【问题描述】:

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

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

编译失败,报错

'class std::vectorstd::__cxx11::basic_string' 中的

'Example' 没有命名类型 朋友 std::vectorstd::string ::Example::GetNames(); ^~~~~~~ main.cpp:25:2: 错误:预期 ';'类定义后

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

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

【问题讨论】:

    标签: c++ class friend


    【解决方案1】:

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

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

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

    您想要告诉编译器有一个名为 Example 的全局命名空间是在函数声明周围放置括号:

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

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

    【讨论】:

    • 值得注意的是,这与区分int (*foo)();int* foo(); 基本相同。有时,声明符语法需要帮助消除歧义。
    • @StoryTeller-UnslanderMonica 就像大多数人类语言一样
    • 是的,忽略错别字...是的,我知道这是它试图做的,但不是如何避免它。
    猜你喜欢
    • 2022-01-23
    • 2014-08-12
    • 2021-02-23
    • 2013-09-18
    • 2013-05-19
    • 2017-05-31
    • 2016-02-24
    • 2014-12-30
    相关资源
    最近更新 更多