函数模板实例化和友元声明 [英] Function template instantiation and friend declaration

查看:24
本文介绍了函数模板实例化和友元声明的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚开始学习 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 operator<< 中调用 operator<<a1<<'\n'?我的猜测是第二个选项是正确的,我基于此摘录 cppreference 表示:

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 起),并且该特定函数尚未显式实例化,发生隐式实例化.

When code refers to a function in context that requires the function definition to exist, or if the existence of the definition affects the semantics of the program (since C++11), and this particular function has not been explicitly instantiated, implicit instantiation occurs.

但是友元声明真的不需要函数定义存在吗?

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.

这篇关于函数模板实例化和友元声明的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆