问题描述
下面的代码不是在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?命名空间模板类“的朋友的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!