具有定义的朋友功能-模板还是非模板? [英] Friend function with a definition - template or non-template?

查看:79
本文介绍了具有定义的朋友功能-模板还是非模板?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有以下代码:

template<class T> struct S;
template<class T> void operator++(S<T>);

template<class T> struct S {
    friend void operator++(S);
};

template<class T>
void operator++(S<T>) {}

int main() {
    S<int> s;
    ++s;
}

这将编译但不会链接,因为friend声明引入了一个从未定义的非模板operator++.

This will compile but won't link, because the friend declaration introduces a non-template operator++, that has never been defined.

此常见问题解答显示为(粗体是我的):

解决方案是说服编译器,因为它正在检查类主体以使 operator++函数本身就是模板.做这件事有很多种方法;

The solution is to convince the compiler while it is examining the class body proper that the operator++ function is itself a template. There are several ways to do this;

第一种方法是将<>添加到好友声明中,这里我不考虑它.第二个是在类主体中定义friend函数":

The first way is to add <> into the friend declaration, and I'm not considering it here. The second is "to define the friend function within the class body":

template<class T> struct S {
    friend void operator++(S) { }
};

引号表明void operator++(S)现在是函数模板,而不是非模板函数.是吗?

The quote suggests that void operator++(S) is now a function template and not a non-template function. Is it?

推荐答案

它不是模板,因为它的声明不是模板的声明(即使它出现在模板声明本身中).

It is not a template, because its declaration is not that of a template (even though it appears inside a template declaration itself).

[临时朋友] (强调我的意思)

[temp.friend] (emphasis mine)

1 类或类模板的朋友可以是功能模板 或类模板,功能模板或类的专业化 模板,或非模板函数或类. 用于朋友功能 不是模板声明的声明:

1 A friend of a class or class template can be a function template or class template, a specialization of a function template or class template, or a non-template function or class. For a friend function declaration that is not a template declaration:

  • 如果好友名称是合格或不合格的模板标识,则好友声明指的是函数的特殊化 模板,否则,

  • if the name of the friend is a qualified or unqualified template-id, the friend declaration refers to a specialization of a function template, otherwise,

如果朋友的名字是一个限定ID,并且在指定的类或名称空间中找到了匹配的非模板函数, 朋友声明引用了该函数,否则,

if the name of the friend is a qualified-id and a matching non-template function is found in the specified class or namespace, the friend declaration refers to that function, otherwise,

如果朋友的名字是一个限定ID,并且在指定的类或名称空间中找到了匹配的函数模板,则该朋友 声明是指该函数的推导专业化 模板([temp.deduct.decl]),否则,

if the name of the friend is a qualified-id and a matching function template is found in the specified class or namespace, the friend declaration refers to the deduced specialization of that function template ([temp.deduct.decl]), otherwise,

名称应为声明(或重新声明)非模板函数的非限定ID .

[示例:

template<class T> class task;
template<class T> task<T>* preempt(task<T>*);

template<class T> class task {
  friend void next_time();
  friend void process(task<T>*);
  friend task<T>* preempt<T>(task<T>*);
  template<class C> friend int func(C);

  friend class task<int>;
  template<class P> friend class frd;
};

在这里,任务类模板的每个专业化都有功能 next_­time作为朋友; 因为process没有明确 template-arguments,任务类模板的每个专业化都有 一个适当类型的函数process作为朋友,并且该朋友 不是功能模板专业化;因为朋友 preempt有一个明确的模板参数T,每个专门化 task类模板的适当地专门化了 作为朋友的功能模板preempt;以及每个专业 task类模板具有函数的所有专业化 模板func作为朋友.同样, task类模板具有类模板专长 task<int>作为朋友,并且拥有该课程的所有专业 模板frd作为朋友. —示例]

Here, each specialization of the task class template has the function next_­time as a friend; because process does not have explicit template-arguments, each specialization of the task class template has an appropriately typed function process as a friend, and this friend is not a function template specialization; because the friend preempt has an explicit template-argument T, each specialization of the task class template has the appropriate specialization of the function template preempt as a friend; and each specialization of the task class template has all specializations of the function template func as friends. Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, and has all specializations of the class template frd as friends.  — end example ]

尽管示例不是规范性的,但引号中的示例阐明了先前规范性文本的意图.由于朋友运算符声明不是模板声明,因此以粗体显示.因此,它声明了一个非模板函数.

While examples are non-normative, the one in the quote clarifies the intent of the preceding normative text. Since the friend operator declaration is not a template declaration, the text in bold applies. It therefore declares a non-template function.

这篇关于具有定义的朋友功能-模板还是非模板?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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