gpt4 book ai didi

c++ - 与模板特化成为 friend 时可能出现 gcc 错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:51:45 24 4
gpt4 key购买 nike

在回答关于 SO 的另一个问题时,我遇到了一个有点可疑的 gcc 编译器错误。有问题的片段是

template <class T> class A;
template <class T, class U>
void operator*(A<T>, A<U>);

template <class T>
class A {
friend void ::operator*(A<T>, A<T>);
...

最后一行给出了著名的警告

friend declaration 'void operator*(A<T>, A<T>)' declares a non-template function

稍后会导致硬错误。完整代码可见here .

现在,问题是我认为这种行为不合适。 [temp.friend]/1 中的标准说:

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

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

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

这是 C++03; C++11 包含类似的子句


模板的特化由 [temp.spec]/4 定义:

... A specialization is a class, function, or class member that is either instantiated or explicitly specialized (14.7.3).

和 [temp.fct.spec]/1:

A function instantiated from a function template is called a function template specialization; so is an explicit specialization of a function template. Template arguments can either be explicitly specified ...

[temp.arg.explicit]/2 说的是关于为函数规范指定模板参数列表:

A template argument list may be specified when referring to a specialization of a function template

...

— in a friend declaration.

Trailing template arguments that can be deduced (14.8.2) may be omitted from the list of explicit template-arguments. If all of the template arguments can be deduced, they may all be omitted; in this case, the empty template argument list <> itself may also be omitted.

因此,通过 [temp.fct.spec]/1,::operator*<T,T>(A<T>, A<T>)是函数模板特化;由于可以推导出模板参数,因此可以称为::operator*(A<T>, A<T>) .所以我得出结论,友元声明中的 qualified-id 表示函数模板特化。


我认为满足了强调的条件;因此,友元声明应该与具有运算符模板(隐式)特化的类成为友元。然而,gcc 不这么认为,并继续讨论第四个项目符号,它只涉及由非限定 id 指定的 friend ,即使该 friend 实际上是由限定 id 命名的

在这种情况下我的解释正确还是 gcc 正确?

最佳答案

我相信 gcc 是正确的。

首先是当前的措辞:

if the name of the friend is a qualified-id and a matching functiontemplate is found in the specified class or namespace, the frienddeclaration refers to the deduced specialization of that functiontemplate (14.8.2.6), otherwise

来自[14.8.2.6 从函数声明中推导模板参数]:

1 In a declaration whose declarator-id refers to a specialization of afunction template, template argument deduction is performed toidentify the specialization to which the declaration refers.Specifically, this is done for explicit instantiations (14.7.2),explicit specializations (14.7.3), and certain friend declarations(14.5.4). This is also done to determine whether a deallocationfunction template specialization matches a placement operator new(3.7.4.2, 5.3.4). In all these cases, P is the type of the functiontemplate being considered as a potential match and A is either thefunction type from the declaration or the type of the deallocationfunction that would match the placement operator new as described in5.3.4. The deduction is done as described in 14.8.2.5.

2 If, for the set of function templates so considered, there is either no match ormore than one match after partial ordering has been considered(14.5.6.2), deduction fails and, in the declaration cases, the programis ill-formed.

在您的情况下,执行模板参数推导,因为 declarator-id 未引用特化。我认为重要的部分是 whose declarator-id refers to a specialization作为这一切发生的条件。简而言之,您需要 <> 14.8.2.6p1 中的第一句话发生(如果我没看错的话)。

更新让我们分解一下这种情况下的 declarator-id 是什么:

qualified-id:
nested-name-specifier templateopt unqualified-id
:: identifier
:: operator-function-id
:: literal-operator-id
:: template-id

从上面的语法可以看出,void ::operator*(A<T>, A<T>):: operator-function-id并且不是 :: template-id .这意味着语法永远不能声明模板函数(如错误消息中所述)。要使其成为模板 ID,您必须使用 operator-function-id < template-argument-listopt>语法。

关于c++ - 与模板特化成为 friend 时可能出现 gcc 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13521546/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com