ang bug?命名空间模板类“的朋友 [英] clang bug? namespaced template class' friend

查看:231
本文介绍了ang bug?命名空间模板类“的朋友的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码不是在clang下编译,而是在gcc和VS下编译:

The following code which doesn't compile under clang but does under gcc and VS:

template<typename T> class bar;

namespace NS
{
    template<typename T>
    class foo
    {
        foo() {}

        template<typename U> friend class bar;
    };
}

template<typename R>
class bar
{
public:
    bar()
    {
        NS::foo<int> f;
    }
};


int main(int, char **)
{
    bar<int> b;        
    return 0;
}

无效:

main.cpp:20:22: error: calling a private constructor of class 'NS::foo<int>'

        NS::foo<int> f;    
                     ^

main.cpp:8:9: note: implicitly declared private here

        foo() {}   
        ^

bar 应该可以访问 foo 的私有构造函数,但它看起来没有。如果我删除命名空间NS ,它会编译。

bar should have access to foo's private constructor but it looks like it doesn't. If I remove namespace NS, it compiles.

代码看起来很好,但也许我误解了C ++标准。哪个编译器是正确的?

Code looks fine to me, but maybe I'm misunderstanding the C++ standard. Which compiler is correct?

推荐答案

我相信clang是正确的。根据[namespace.memdef] / 3:

I believe that clang is correct. According to [namespace.memdef]/3:


命名空间中首先声明的每个名称都是该命名空间的成员。如果
非本地类中的 friend 声明首先声明类,函数,类模板或函数模板,则该朋友是成员
最内层的命名空间。

Every name first declared in a namespace is a member of that namespace. 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.

在您的情况下,名称不会显示为由 friend 声明。然而,在该段落的后面,强调我:

In your case, the name wouldn't appear to be "first declared" by the friend declaration. Later in that paragraph, however, emphasis mine:


如果朋友声明既不合格也不是一个 template-id
声明是一个函数或一个 elaborated-type-specifier ,查找来确定实体是否
之前已声明不会考虑最内层命名空间之外的任何作用域。

If the name in a friend declaration is neither qualified nor a template-id and the declaration is a function or an elaborated-type-specifier, the lookup to determine whether the entity has been previously declared shall not consider any scopes outside the innermost enclosing namespace.

,该声明:

template<typename U> friend class bar;

不会在 bar code> namespace NS ,所以它不会找到你的早期声明。因此,它声明一个类模板 NS :: bar< typename> 朋友 $ c> foo 。您必须限定 bar 的名称才能找到

will not look for bar outside of namespace NS, so it will not find your earlier declaration. As such, it declares a class template NS::bar<typename > to be a friend of foo. You will have to qualify the name bar in order for it to be found:

template<typename U> friend class ::bar;

这似乎与 GCC Bug 37804

这篇关于ang bug?命名空间模板类“的朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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