问题描述
我刚刚开始学习 C++ 模板,为了练习目的,我编写了这个简单的代码
I've just started learning templates in C++ and for practice purposes wrote this simple code
#include <iostream>
template<typename T>
class A;
template<typename T>
std::ostream& operator<<(std::ostream& out, A<T> x);
template <typename T>
class A
{
T m_x = 10;
public:
A(T x) : m_x{ x } {}
friend std::ostream& operator<< <T>(std::ostream& out, A x);
};
template<typename T>
std::ostream& operator<<(std::ostream& out, A<T> x)
{
out << "m_x = " << x.m_x;
return out;
}
int main()
{
A<int> a1{ 10 };
std::cout << a1 << '\n';
}
它按预期工作,即我得到 10
作为输出,但有一件事困扰着我.operator<<
函数在哪一点被实例化?它是在创建 a1
对象时发生(这也是 A<int>
隐式实例化的点,对吗?)还是在我创建时发生在 std::cout
?我的猜测是第二个选项是正确的,我基于此摘录 cppreference 表示:operator<<
中调用 operator<<
a1<<'\n'
It works as expected, that is I get 10
as the output, but there is one thing that bothers me. At which point is the operator<<
function instantiated? Does it happen at the point of creation of the a1
object (this is also the point where A<int>
is implicitly instatiated, right?) or does it happen when I call the operator<<
in std::cout << a1 << '\n'
? My guess is that the second option is correct and I base it on this excerpt from cppreference which says that:
当代码在上下文中引用需要函数定义存在的函数时,或者如果定义的存在影响程序的语义(C++11 起),并且该特定函数尚未显式实例化,发生隐式实例化.
但是友元声明真的不需要函数定义存在吗?
But is it true that a friend declaration does not require the function definition to exist?
如果这个问题措辞不当,我很抱歉,我已尽力正确使用命名法,但我只是一个初学者.
I'm sorry if this question is ill-pharased, I did my best to use the nomenclature right, but I'm just a beginner.
编辑
这个怎么样?
template <typename T>
class foo
{
T m_x;
friend void bar(foo x)
{
x.m_x = "123";
}
};
如果我将友元函数定义放在一个类中,该类的每个实例化都会导致创建一个新的、普通的函数重载,它采用当前特化的参数,因此我希望我一写完就看到一个错误:foox;
但我没有得到一个...(例如, bar(x);
导致错误)
if I put a friend function definition inside a class, every instantiation of that class causes a new, ordinary function overload to be created that takes an argument of the current specialization, hence I would expect to see an error as soon as I write this: foo<int> x;
but I don't get one... (for example, bar(x);
causes the error)
推荐答案
operator<<
的重载在您的情况下为每个模板类提供了单独的重载A<T>
,所以我可以假设,operator<<
的实例化可以与您的类 A
的每个实例化一起.
The overload of the operator<<
in your case gives you an individual overload to every template classA<T>
, so I can assume, that instantiation of operator<<
can be with every instantiation of your class A<T>
.
您可以查看这篇帖子,它对您的情况很有用.
You can checkout this post, it can be useful in your case.
这篇关于函数模板实例化和友元声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!