【问题标题】:Nested Classes and ADL嵌套类和 ADL
【发布时间】:2015-12-31 18:30:41
【问题描述】:

代码如下:

namespace Namespace
{
    struct L0
    {
        enum SomeEnum
        {
            EnumVal
        };

        struct L1
        {
            friend void f(SomeEnum)
            {
                std::cout << "f()" << std::endl;
            }
        };

        friend void g(SomeEnum)
        {
            std::cout << "g()" << std::endl;
        }
    };
}

int main()
{
    f(Namespace::L0::EnumVal); // error: f not defined
    g(Namespace::L0::EnumVal); // good
}

这里的思路是让编译器通过ADL找到f()和g()。

但是,此代码无法使用 gcc 或 clang 编译。类似的代码似乎在 MSVC 下编译得很好。

也许我错过了一些东西,但我真的不明白代码有什么问题,以及它是否有问题。如果有人能对此有所了解,那就太好了。

PS。新年快乐:)

【问题讨论】:

    标签: c++ class enums nested argument-dependent-lookup


    【解决方案1】:

    SomeEnum 不是 L1 的成员,因此 ADL 找不到 L1 中定义的函数。

    我相信,这是您正在寻找的报价:

    首先在类或类模板 X 中的友元声明中声明的名称成为 X 的最内层封闭命名空间的成员,但不能用于查找(除了考虑 X 的参数相关查找),除非在提供了命名空间范围 - 有关详细信息,请参阅命名空间。

    【讨论】:

    • 不应该检查 SomeEnum 最里面的命名空间吗?
    • @dsi,不,你为什么这么认为?
    • 我依赖 cppreference.com 说:“4)对于枚举类型的参数,定义枚举的命名空间被添加到集合中。如果枚举类型是类,该类被添加到集合中。”
    • @dsi,真的。但在您的情况下, SomeEnum 不是 L1 的成员。所以L1没有添加到集合中。我不确定是什么让你感到困惑。
    • 我的意思是,对于 SomeEnum 命名空间命名空间应该添加到集合中,并且AFAIK函数 f() 正在这个命名空间中定义(因为它是它的最里面的命名空间),所以它应该被 ADL 发现
    猜你喜欢
    • 2018-09-10
    • 1970-01-01
    • 1970-01-01
    • 2010-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多