问题描述
如果我有一个普通的课堂,我可以在课堂内注入一个非自由的朋友函数。 (这只能由ADL找到。)
If I have a normal class I can "inject" a non-free friend function inside the class. (That among other things can be only be found by ADL).
情况1:
class A{
double p_;
friend double f(A const& a){return a.p_;}
};
如果这是模板类,我可以做:
If instead this is a template class I can do:
情况2:
template<class T>
class A{
double p_;
friend double f(A const& a){return a.p_;} // apparently A const& is a synomyn for A<T> const&
};
现在假设我需要实现 f
就需要稍后定义的类而言。我遇到这种情况,我尝试这样做:
Now suppose that I need to implement f
in terms of a class that needs to be defined later. I such case I tried doing this:
情况3:
template<class T>
class A{
double p_;
friend double f(A const& a);
};
...
这已经发出警告:警告:朋友声明'double f (const A&)'声明了非模板函数[-Wnon-template-friend]。
This already gives a warning: "warning: friend declaration ‘double f(const A&)’ declares a non-template function [-Wnon-template-friend]".
按照编译器的建议,我可以这样做:
Following the advice from the compiler I can do this:
template<class T> class A;
template<class T> double f(A<T> const& a);
template<class T>
class A{
double p_;
friend double f<>(A const& a);
};
template<class T> double f(A<T> const& a){return a.p_;}
更多的代码,我什至不能确定它与我想要的情况2 abov是否100%等效,因为现在我有了一个真正的自由函数,恰好是朋友而不是注入的朋友。
Which requires so much more code and I am not even sure it is 100% equivalent to case 2 abov which is what I want, because now I have a truly free function that happens to be a friend instead of an injected friend.
案例3是否可以修改为100%等同于案例2,并且在类外仍然具有 f
的定义?换句话说,可以注入类之外定义的朋友功能吗?
Can case 3 be modified to be 100% equivalent to case 2 and still have a definition of f
outside the class? In other words can one inject a friend function that is defined out of the class?
template<class T>
class A{
double p_;
friend double f(A<T> const& a);
};
template<class T> double A<T>::f(A<T> const& a){return a.p_;}
此答案找到相同的解决方案,但没有回答关于案例3等同于案例2的问题。
推荐答案
Friend函数具有特殊的可见性规则(ADL的特殊情况),因此在类外部定义函数与在内部定义函数总是不同的。
此外,在第2种情况下,该功能为非模板。即使每个模板都有一个。因此,要在类
之外实现它,您必须为每个<$ c实现每个 friend double f(A< C const& a);
$ c> T 。
The advice is the most close workaround:
your function is declared outside, so its visibility is "different".
其他解决方法是声明一个私有方法来完成这项工作,从而使您能够在类中有朋友定义。
然后可以在以后定义该私有方法:
template<class T>
class A{
double p_;
double do_f() const;
friend double f(A const& a){return a.do_f();}
};
// Thing needed by A<T>::do_f
template<class T>
double A<T>::do_f() const
{
// ...
}
如果返回类型为不完整类型,则必须使用 auto return(在g ++ 11和clang ++ 11中有效)。
If the return type is an incomplete type you have to do a trick with
auto
return (this works in g++11 and clang++11).
template<class T> class A;
class B;
template<class T>
class A{
B do_f() const;
friend auto f(A const& a){return a.do_f();} // not friend B f(...
};
class B{};
template<class T> B A<T>::do_f() const{return B{};}
int main(){A<double> a; f(a);}
这篇关于在模板类之外定义朋友函数的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!