[英]How to define a friend function declared in a non template class internal to a template class outside of both classes?
I found "how to define a friend template function of a template class outside of its declaration" ( SO / cppreference ), but how to do that if we add another internal non template class in the mix? 我发现“如何在其声明之外定义模板类的朋友模板函数”( SO / cppreference ),但是如果我们在混合中添加另一个内部非模板类,该怎么做呢?
Ie how to (externally) define operator<<
declared in class Internal
from the following example: 即如何(从外部)定义在
class Internal
声明的operator<<
,来自以下示例:
#include <iostream>
template <typename T>
class External {
public:
explicit External(T initial) : value{initial} {}
class Internal {
public:
Internal(const External& e) : internal_value{e.value} {}
private:
friend std::ostream& operator<<(std::ostream& os, const Internal& i);
// ^^^ this one
/* body
{
return os << i.internal_value;
}
*/
T internal_value;
};
friend std::ostream& operator<<(std::ostream& os, const External& e)
{
return os << Internal{e};
}
private:
T value;
};
int main()
{
std::cout << External<int>{5};
}
Here's the issue. 这是问题所在。 Despite the fact that
External
is a template and Internal
is a dependent type. 尽管
External
是模板而Internal
是依赖类型。 The friend function is not templated itself. 朋友的功能本身并不是模板化的。 Odd as it may seem, it doesn't depend on the template parameter.
看似奇怪,它不依赖于模板参数。
When you define it inline, then each specialization of the template creates the associated friend function as well. 当您将其内联定义时,模板的每个特化也会创建相关的友元函数。 But when it's not inline you need to provide the definition of the operator for each specialization explicitly .
但是当它不是内联时,你需要明确地为每个特化提供运算符的定义。 And you can't do that with a template, since the function is not a template.
并且你不能用模板做到这一点,因为该函数不是模板。
So if you add this after the template declaration: 所以如果你在模板声明后添加它:
std::ostream& operator<<(std::ostream& os, External<int>::Internal const& i)
{
return os << i.internal_value;
}
It will build. 它会建立。 And as you can see, only concrete types are being used in the function.
正如您所看到的,函数中只使用了具体类型。
Obviously that isn't much of a solution. 显然,这不是一个解决方案。 Any sensible person would want specializations of
External
to generate the friend definition as well. 任何明智的人都会想要
External
专业化来生成朋友定义。 The way to accomplish that in a maintainable fashion is to keep the operator definition inline , but instead of doing the work there, delegate to a member function (which is dependent on the template parameter): 完成在一个可维护的方式的方式是保持,但而不是做的工作有运营商定义的内联 ,委托给一个成员函数(这取决于模板参数):
class Internal {
public:
Internal(const External& e) : internal_value{e.value} {}
private:
std::ostream& print(std::ostream&) const;
friend std::ostream& operator<<(std::ostream& os, Internal const& i)
{
return i.print(os); // Short and sweet on account of being inline
}
T internal_value;
};
//....
template<typename T>
std::ostream& External<T>::Internal::print(std::ostream& os) const {
// Provided outside of the class definition, can be as verbose as you like
return os << internal_value;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.