C++中的特定模板友谊

Tia*_*nyi 7 c++ templates access-control friend

我对C++中的特定模板友谊有疑问.在C++ Primer一书中,具体的模板友谊是这样编写的:

 template <class T> class Foo3;
 template <class T> void templ_fcn3(const T&);
 template <class Type> class Bar {
     // each instantiation of Bar grants access to the
     // version of Foo3 or templ_fcn3 instantiated with the same type
     friend class Foo3<Type>;
     friend void templ_fcn3<Type>(const Type&);
     // ...
 };
Run Code Online (Sandbox Code Playgroud)

特别的一点是,有

<Type>
Run Code Online (Sandbox Code Playgroud)

friend语句中的类或函数名之后.

但是,在实践中,如果我写这个:

template <class Type> class T_CheckPointer;
template <class T> T_CheckPointer<T> operator+(const T_CheckPointer<T> &, const size_t n);

template <typename Type>
class T_CheckPointer {

    // Specific Template Friendship
    friend T_CheckPointer<Type>
    operator+ <Type> (const T_CheckPointer<Type> &, const size_t n);

// other code...

}
Run Code Online (Sandbox Code Playgroud)

在实例化模板功能期间会出错.

如果我改变了

// Specific Template Friendship
friend T_CheckPointer<Type>
    operator+ <Type> (const T_CheckPointer<Type> &, const size_t n);
Run Code Online (Sandbox Code Playgroud)

// Specific Template Friendship
friend T_CheckPointer<Type>
    operator+ <> (const T_CheckPointer<Type> &, const size_t n);
Run Code Online (Sandbox Code Playgroud)

通过删除功能名称后面的单词类型,那么一切都会好的.

谁能告诉我原因?


有关信息,我打电话时会出现错误消息

int iarr[] = {1, 2, 3, 4};
T_CheckPointer<int> itcp(iarr, iarr+4);
Run Code Online (Sandbox Code Playgroud)

错误信息:

/usr/include/c++/4.4/bits/stl_iterator_base_types.h: In instantiation of ‘std::iterator_traits<int>’:
/usr/include/c++/4.4/bits/stl_iterator.h:96:   instantiated from ‘std::reverse_iterator<int>’
../Classes/T_CheckPointer.hpp:31:   instantiated from ‘T_CheckPointer<int>’
../PE16.cpp:520:   instantiated from here
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:127: error: ‘int’ is not a class, struct, or union type
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:128: error: ‘int’ is not a class, struct, or union type
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:129: error: ‘int’ is not a class, struct, or union type
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:130: error: ‘int’ is not a class, struct, or union type
/usr/include/c++/4.4/bits/stl_iterator_base_types.h:131: error: ‘int’ is not a class, struct, or union type
Run Code Online (Sandbox Code Playgroud)

eca*_*mur 4

这是一个最小的例子:

template<typename T> struct U { typedef typename T::X X; };
template<typename T> void foo(typename U<T>::X);

template<typename T> struct S;
template<typename T> void foo(S<T>);
template<typename T> struct S { friend void foo<T>(S<T>); };

template struct S<int>;
Run Code Online (Sandbox Code Playgroud)

声明失败的原因friend是,通过提供模板参数的完整列表,您要求编译器专门化所有可用的函数模板并选择与签名最匹配的模板。对第一个定义的特化foo会导致U对导致格式错误的程序的参数进行特化。

相反,如果您省略模板参数,它将从参数中推导出来。因此,模板参数推导是根据14.8.2 [temp.deduct]执行的,特别是 14.8.2p8 适用,这意味着 的 特化中的替换失败U不是错误 (SFINAE)。

这是在可以从上下文推导出模板参数的任何地方省略模板参数的一个很好的理由(例如,这里是函数或运算符参数类型)。请注意,您仍然需要提供<>括号以确保将其operator +读取为模板 ID ( 14.5.4 [temp.friend] )。