嵌套类友元函数访问在 gcc 和 clang 中有效,但在 msvc 中无效

Nested class friend function access works in gcc and clang but not in msvc

提问人:user12002570 提问时间:11/11/2023 最后编辑:user12002570 更新时间:11/12/2023 访问量:71

问:

我有这个程序,在类中定义了一个朋友函数,它使用 gcc 和 clang 进行编译,但被 msvc 拒绝。

#include <iostream>
template<typename T>
class Outer
{
     struct Inner;
     friend void foo(); 
};

template<typename T>
struct Outer<T>::Inner
{
  friend void bar(Inner) 
  { 
    //gcc and clang accepts but msvc rejects this 
    typename Outer<int>::Inner k;    
    std::cout << "bar called";
  }
};
void foo()
{
    std::cout << "foo called";
    Outer<int>::Inner i;
    bar(i);    
}
int main()
{
    Outer<int> outer;
    foo();
}

工作演示

根据标准,哪个编译器在这里?

MSVC 说道:

<source>(14): error C2248: 'Outer<int>::Inner': cannot access private struct declared in class 'Outer<int>'
<source>(5): note: see declaration of 'Outer<int>::Inner'
<source>(14): note: see declaration of 'Outer<int>'
<source>(14): note: the template instantiation context (the oldest one first) is
<source>(17): note: see reference to class template instantiation 'Outer<T>::Inner' being compiled
<source>(14): note: see reference to class template instantiation 'Outer<int>::Inner' being compiled
<source>(12): note: while compiling class template member function 'void bar(Outer<int>::Inner)'
<source>(22): note: see the first reference to 'bar' in 'foo'
Compiler returned: 2
C++ 语言-律师 朋友 类-模板

评论

0赞 Pete Becker 11/11/2023
次要观点:“内部类”在 C++ 中不是一回事。在 C++ 中,在另一个类中定义的类是嵌套类。这没什么大不了的,只是在某些语言中,“内部”类具有特殊属性。
0赞 user12002570 11/11/2023
@PeteBecker 是的,我同意并理解。只是出于外行/休闲目的,或者更确切地说,由于术语“内部”通常确实传达(在 C++ 中)我们正在谈论“嵌套”,我经常使用前一个术语。当然,正如你所说,技术上准确的术语是“嵌套”。

答:

3赞 user12002570 11/11/2023 #1

Gcc 和 Clang 接受该程序是错误的,因为在嵌套类中定义的友元函数对封闭类的成员没有特殊的访问权限。这可以从 class.nest 中看出:

与成员函数一样,在嵌套类中定义的友元函数 ([class.friend]) 位于该类的词法范围内;它遵循与该类的静态成员函数 ([class.static]) 相同的名称绑定规则,但它对封闭类的成员没有特殊访问权限。


换句话说,无法访问私有字段,因此程序格式不正确barInnerOuter<T>