本文介绍了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 声明。然而,在该段落的后面,强调我:

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

,该声明:

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;

这似乎与。

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

05-27 18:03
查看更多