将类的静态函数声明为友元函数

3
我的问题是,据我所知,在将函数声明为友元之前,必须进行前向声明或定义。下面的代码是否有效?
template <typename> class class1;

template <typename T>
class class2 {
    ...
    friend void class1<T>::foo();
    ...
}

template <typename T>
class class1 {
    ...
    static void foo() {}
    ...
}

这里的问题在于你无法前向声明静态函数foo。希望这些信息足以回答这个问题。我尝试了类似以下的代码,它编译并运行良好。但我想知道这是否仍然被认为是有效的,因为我还读到一些编译器可以接受友元声明而不需要先前的前向声明,尽管这取决于编译器。
1个回答

1

无论你喜欢与否,将某个东西声明为 friend 会在类外创建前向声明。这在标准中明确写出,编译器也支持这一点。

你的例子更加复杂。你试图从前向声明内部使用某些内容。好吧,聪明的编译器可能会处理这个问题。但并不是所有编译器都能做到。第二点——你的 friend 声明在模板内部。编译器只能部分解析模板。他们不能做得更好。所有替换和检查只发生在模板被实例化时。此时编译器了解得更多。在你的示例中,class2 永远不会被实例化。

尝试在模板内写入一些奇怪的内容,你会发现这会编译通过。然后添加实例化而不改变模板本身。编译器会给你错误。


我认为我误解了有关前向声明和友元的阅读内容。C++ primer指出:“一些编译器允许在没有普通声明的情况下调用友元函数。即使您的编译器允许这样的调用,也最好为友元提供单独的声明。”我认为我理解为在将函数声明为友元之前必须存在前向声明,但实际上它意味着对于类的用户来说,调用该函数必须存在声明,因此它实际上可以在类定义之后存在? - JustinBlaber
你可以在任何地方多次放置相同的前向声明。Friend创建一个。它是否已经存在并不重要。单独创建前向声明是一个风格问题。我建议这样做,但只是为了清晰和易读。这不会改变代码的含义。 - Kirill Kobelev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接