我正在使用朋友函数,但面临一个问题,似乎可以用MSVC编译,但不能用gcc和clang编译。下面是一个简化的例子来展示这个问题:
#include <iostream>
template<typename T>
class Outer
{
struct Inner;
friend void foo();
};
template<typename T>
struct Outer<T>::Inner
{
template<typename S> friend void bar(typename Outer<S>::Inner);
};
template<typename S> void bar(typename Outer<int>::Inner) //but this private access works in msvc but not in gcc and clang?
{
//typename Outer<int>::Inner k; //doesn't work as expected in all compilers(including msvc)
std::cout << "bar called";
}
void foo()
{
std::cout << "foo called";
Outer<int>::Inner i;
bar<int>(i);
}
int main()
{
Outer<int> outer;
foo();
}
字符串
Demo
上面的程序可以在msvc下工作,但不能在gcc和clang下工作。Gcc的代码是error: struct Outer<int>::Inner is private within this context
。正确的行为是什么?
还有一种方法可以让程序与所有编译器一起工作吗?
1条答案
按热度按时间2cmtqfgy1#
MSVC在这里似乎是错误的,因为
Outer<T>::Inner
是Outer<T>
的私有成员。有没有一种方法可以让程序在所有编译器上都能工作?
是的,您可以在
Outer
中添加一个 *friend template声明 *,这样函数模板bar
也是Outer
的friend,如下所示。方法一
这里我们在
bar
的Outer
中添加一个friend模板声明。字符串
Working demo
请注意,在这种特殊情况下,您可以省略
Inner
中的完整friend模板声明,因为您实际上并没有从foo
访问Inner
的任何私有内容。Demo