7

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&);
     // ...
 };

特筆すべきは

<Type>

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...

}

テンプレート関数のインスタンス化中にエラーが発生します。

そして私が変わると

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

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

関数名の後の単語タイプを削除することで、すべて問題ありません。

誰でも理由を教えてくれますか?


詳細については、電話をかけるとエラーメッセージが表示されます

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

エラーメッセージ:

/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
4

1 に答える 1

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>;

宣言が失敗する理由はfriend、テンプレート引数の完全なリストを提供することにより、コンパイラーが使用可能なすべての関数テンプレートを特殊化し、署名に最も一致するものを選択するように要求しているためです。foo結果の最初の定義を特殊化するUと、プログラムの形式が正しくないという引数を使用して特殊化することになります。

代わりにテンプレート引数を省略すると、引数から推測されます。このようなテンプレート引数の推論は14.8.2[temp.deduct]に従って実行され、特に14.8.2p8が適用されます。これは、の特殊化における置換の失敗がUエラーではないことを意味します(SFINAE)。

これは、コンテキストから推測できる場所(ここでは関数または演算子のパラメーター型など)でテンプレート引数を省略するのに十分な理由です。がtemplate-id14.5.4 [temp.friend] )として読み取られるようにするには、<>角かっこを指定する必要があることに注意してください。operator +

于 2012-10-09T17:05:23.193 に答える