繁体   English   中英

朋友没有<>的模板专业化

[英]friend a template specialization without <>

C ++ 03和C ++ 11在[temp.friend]的第一段中:

[编辑报价。 第一次尝试错过了措辞的第二个差异。]

对于不是模板声明的朋友函数声明:

  1. 如果好友的名称是合格或不合格的template-id ,则好友声明引用功能模板的特殊化;否则

  2. 如果朋友的名字是qualified-id,并且在指定的类或名称空间中找到了匹配的非模板函数,则friend声明引用该函数,否则,

  3. [C ++ 03:]如果朋友的名字是一个限定ID,并且在指定的类或名称空间中找到了功能模板的匹配专业化,则friend声明引用该功能模板专业化,否则,

    [C ++ 11:]如果朋友的名称是一个限定ID ,并且在指定的类或名称空间中找到了匹配的功能模板,则friend声明将引用该功能模板的推论专业化,否则,

  4. 名称应为声明(或重新声明)普通(非模板)功能的非限定ID

[措辞上的变化对我来说似乎是澄清。 尽管我猜想可能会有不同的方式来解释C ++ 03的措辞,即“在类或名称空间中查找特殊化”。]

我对第三个子弹感到好奇。 我写了这段代码来尝试满足其要求,但是无论是-std = c ++ 03还是-std = c ++ 11,g ++ 4.8.1和clang ++ 3.4都拒绝该代码:

template <class T> class R;
namespace N {
    template <class T> void test(const R<T>&);
}

template <class T>
class R {
    friend void N::test(const R<T>&);  // 8
    int m;
};

template <class T>
void N::test(const R<T>& rec) { rec.m; }

int main() {
    R<int> r;
    N::test(r);
}

当然如果我将第8行更改为

friend void N::test<>(const R<T>&);

第一个项目符号适用,并且该程序被接受。 g ++会显示一条有用的警告,说该朋友“声明了非模板函数”,并暗示我可能想这样做。 为了清晰和安全起见,该代码可能还会获得更多样式点。

但是上面的代码不应该被第三个项目符号覆盖并且有效吗? 朋友声明不是模板声明,并且使用不是模板ID限定 ID作为名称。 而且没有非模板函数声明可与第二个项目符号匹配。

这仅仅是两者共同的编译器错误吗? 还是我误解了一些东西,如果是的话,是否有一个示例程序可以演示第三个项目符号?

在// 8行,将代码修改为: friend void N::test< R<T> >( R<T>&); 也正确。

friend void N::test<R<T>>(const R<T>&);//one type is friend with one type  #1
friend void N::test<>(const R<T>&);// one type is friend with one type    #2

我使用一些代码证明#1等于#2

最后,我尝试回答您的问题。我不确定那是正确的。

 friend void N::test(const R<T>&);

实例化类R时, R<T>是已知类型。 但是,功能是

声明为好友函数,并且实际上不实例化函数模板,则

朋友功能是不存在的功能。 从语法的角度来看,

编译器会提示您它是函数而不是模板

N::test (r);

在这个地方,函数被实例化,但是编译器与

在R类中声明之前的朋友,因为您没有在R中声明为模板

类,您只需声明一个函数。

我认为<>是进行扣除的条件,因为从14.8.2.6开始,

在声明符的declarator-id引用功能模板的特殊化的声明中,执行模板参数推导来标识声明所引用的特殊化。 具体来说,这是针对显式实例化(14.7.2),显式专业化(14.7.3)和某些朋友声明(14.5.4)完成的。

在这种情况下,declarator-id不是专门的,因此不会进行推论。

N :: test是一个模板函数,它采用一个名为T的类。 它不需要名为R<T> 适当更改功能即可使用。

namespace N
{
    template <class T>
    void test ( const T & );
}

template <class T>
class R
{
    friend void N::test ( const R<T> & );
    int m;
};

template <class T>
void N::test ( const T & rec ) { rec.m; }

int main ( )
{
    R<int> r;
    N::test ( r );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM