无法显式访问名称空间范围的朋友 [英] cannot access namespace scope friend explicitly

查看:80
本文介绍了无法显式访问名称空间范围的朋友的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天遇到一个问题,即ADL找不到在类内部定义的类型的静态成员函数。

I had an issue today where ADL wasn't finding a static member function for a type defined inside a class.

在下面的示例中, str(foo :: Foo :: Enum)在没有显式作用域的情况下不是通过ADL定位的, foo :: Foo :: str(foo :: Foo :: Enum)

That is, in the below example, str(foo::Foo::Enum) isn't located via ADL without explicitly scoping it, foo::Foo::str(foo::Foo::Enum)

namespace foo {

struct Foo
{
    enum Enum
    {
        FOO1,
        FOO2
    };

    static const char* str(Enum e);
};

}

foo::Foo::Enum e = foo::Foo::FOO1;
const char* s = str(e);              // ADL doesn't work

我发现这个 SO问题,并按照接受的答案所述,将其更改为 friend 函数导致ADL现在可以工作。

I found this SO question, and as stated in the accepted answer, changing it to a friend function results in ADL now working.

namespace foo {

struct Foo
{
    enum Enum
    {
        FOO1,
        FOO2
    };

    friend const char* str(Enum e);  // note str is now a friend
};

}

foo::Foo::Enum e = foo::Foo::FOO1;
const char* s = str(e);              // ADL works now

虽然这现在对ADL有所帮助,但我惊讶地发现自己无法通过使用命名空间 foo

Whilst this now helps ADL, I was surprised to find that I couldn't access str by scoping it with a namespace foo

foo::Foo::Enum e = foo::Foo::FOO1;
const char* s = foo::str(e);         // error: ‘str’ is not a member of ‘foo’

我运行了一个测试,其中我打印了 __ PRETTY_FUNCTION __ 的结果,更惊讶地发现str的范围显然是 foo ::

I ran a test, where I printed out the result of __PRETTY_FUNCTION__, and was even more surprised to see that the scope of str is apparently foo:::

__PRETTY_FUNCTION__: const char* foo::str(foo::Foo::Enum)

以下工作示例:

#include <iostream>

namespace foo {

struct Foo
{
    enum Enum
    {
        FOO1,
        FOO2
    };

    friend const char* str(Enum e)
    {
        return __PRETTY_FUNCTION__;
    }
};

}

int main()
{
    foo::Foo::Enum e = foo::Foo::FOO1;

    std::cout << str(e) << '\n';
    // std::cout << foo::str(e) << '\n'; // error: ‘str’ is not a member of ‘foo’

    return 0;
}

输出:

$ ./a.out
const char* foo::str(foo::Foo::Enum)

问题:


  • 为什么我无法找到 str(..)明确地用封闭的名称空间对其进行范围界定?

  • 为什么 __ PRETTY_FUNCTION __ 说它在 foo :: 中,但是我却找不到它吗?

  • Why am I unable to locate str(..) explicitly scoping it with the enclosing namespace?
  • Why does __PRETTY_FUNCTION__ say it's in foo::, and yet I am unable to locate it as such?

推荐答案



  • 为什么找不到 str(..)明确地用封闭的名称空间对其进行范围界定?

  • Why am I unable to locate str(..) explicitly scoping it with the enclosing namespace?

根据标准 [namespace.memdef] / 3


如果非本地类中的朋友声明首先声明了一个类,
函数,类模板或函数模板,则该朋友为一个最里面的封闭命名空间的成员
。朋友声明不会
本身使名称对不合格查找或合格
查找可见。 [注:如果在名称空间范围
中提供了匹配的声明(在授予友谊的类定义之前或之后),则朋友的名称将在其
命名空间中可见。
—注释]

If a friend declaration in a non-local class first declares a class, function, class template or function template the friend is a member of the innermost enclosing namespace. The friend declaration does not by itself make the name visible to unqualified lookup or qualified lookup. [ Note: The name of the friend will be visible in its namespace if a matching declaration is provided at namespace scope (either before or after the class definition granting friendship). — end note ]

这意味着 str 不可见命名查找;

That means str is not visible to name lookup; it can only be called via ADL.



  • 为什么 __ PRETTY_FUNCTION __ 说它在 foo :: 中,但是我却不能这样找到它?

  • Why does __PRETTY_FUNCTION__ say it's in foo::, and yet I am unable to locate it as such?

来自朋友] / 6


只有当该类为非本地类([class.local]),函数名称不合格,并且函数具有名称空间范围。

A function can be defined in a friend declaration of a class if and only if the class is a non-local class ([class.local]), the function name is unqualified, and the function has namespace scope.

str 确实成为命名空间 foo 的成员;

str does become member of namespace foo; it's just invisible.

cppreference.com


friend 声明成为X的最内层命名空间的成员,但它们对 lookup (既不合格也不合格)在类定义之后。可以通过同时考虑名称空间和类的 ADL 找到该名称。 p>

Names introduced by friend declarations within a non-local class X become members of the innermost enclosing namespace of X, but they do not become visible to lookup (neither unqualified nor qualified) unless a matching declaration is provided at namespace scope, either before or after the class definition. Such name may be found through ADL which considers both namespaces and classes.

这篇关于无法显式访问名称空间范围的朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆