最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

为什么在没有模板声明的情况下在模板类中包含使用模板参数的友元函数的实现?

网站源码admin25浏览0评论
本文介绍了为什么在没有模板声明的情况下在模板类中包含使用模板参数的友元函数的实现?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时送ChatGPT账号..

给定以下代码.

#include <iostream>
template<typename T>
class Foo 
{
public:
    Foo(const T& value = T());

    friend Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs)
    {
    // ...
    }
    friend std::ostream& operator<< (std::ostream& o, const Foo<T>& x)
    {
    // ...
    }
private:
    T value_;
};

编译器可以轻松编译具有模板参数且没有以下语法的友元函数

The compiler has no trouble compiling both friend functions which have template parameters without having the following syntax

template <typename T>
friend Foo<T> operator+ (const Foo<T>& lhs, const Foo<T>& rhs)

friend Foo<T> operator+ <>(const Foo<T>& lhs, const Foo<T>& rhs)

friend Foo<T> operator+ <T>(const Foo<T>& lhs, const Foo<T>& rhs)

因为它们是由它们在模板类本身内部的实现定义的.

because they have been defined by their implementation inside the template class itself.

编译器如何在不包含模板声明的情况下编译这些带有模板参数的友元函数?为什么只在类中实现它们就足够了?

How can the compiler compile these friend functions with their template parameters without including a template declaration? Why is just having their implementation inside of the class enough?

我从这里的部分了解了这个概念为什么我在使用模板好友时会出现链接器错误?"

I learned about this concept from here under the section on "Why do I get linker errors when I use template friends?"

推荐答案

这两个选项,有和没有 template,做的事情略有不同.

Those two options, with and without template<class T>, do slightly different things.

当你以这种方式引入一个 friend 函数时,你在封闭的命名空间中以一种只能通过 ADL(参数依赖查找)访问的方式引入它.

When you introduce a friend function that way, you introduce it within the enclosing namespace in a way that is only reachable via ADL (argument dependent lookup).

template 引入了函数模板,没有引入了实际函数的模板.

The template<class T> introduces a function template, and the one without introduces an actual function.

所以:

template<class T>
struct foo {
  friend void bar(foo<T>){}
};

表示当foo存在时,创建一个函数bar(foo).然后 foo 创建 bar(foo).

means that when foo<int> exists, a function bar(foo<int>) is created. Then foo<double> creates bar(foo<double>).

这些 bar 中的每一个都不是 template 函数.它们是一个具有固定签名的函数,一个新的重载,类似于你写的

Each of these bars are not template functions. They are eaxh a function with a fixed signature, a new overload, imilar to if you wrote

void bar(foo<char>){}

紧跟在 foo 之后.唯一的例外是 friend bar 只能通过 ADL 找到,这改变了冲突和重载解决的工作方式.

right after foo. The exception is that the friend bar can only be found via ADL, which changes how conflicts and overload resolution works.

现在这个:

template<class T>
struct foo {
  template <typename X>
  friend void bar(foo<X>){}
};

foo 的每个实例创建一个 template bar.这些并不冲突,因为它们只能通过 ADL 找到.唯一可以找到的是 TX 匹配的那个(在这种情况下 - 有更多参数可能会有所不同).

creates a template bar for each instance of foo. These do not conflict, because they are only found via ADL. And the only one that can be found is the one where the T matches the X (in this case -- with more arguments it could differ).

根据我的经验,制作 template 版本很少是一个好主意.

It is rarely a good idea to do the template version, in my experience.

这篇关于为什么在没有模板声明的情况下在模板类中包含使用模板参数的友元函数的实现?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

发布评论

评论列表(0)

  1. 暂无评论