0

テンプレート化されたクラスのフレンド関数を定義する必要があります。関数には、クラスのメンバー型である戻り値の型があります。戻り値の型はその時点では不明であるため、事前に宣言することはできません。このようなもの

template<class T> class A; 

//This doesn't work: error: need ‘typename’ before...  
template<class T> A<T>::member_type fcn(A<T>::member_type);

//This doesn't work: error: template declaration of ‘typename...
template<class T> typename A<T>::member_type fcn(A<T>::member_type);

template<class T>
class A{
public:
  typedef int member_type;
  friend member_type fcn<T>(member_type);
};

どうすればいいですか?

4

4 に答える 4

1

これは今では他の誰かの答えと重複しているかもしれませんが、ここに完全テスト可能な解決策があります。最後の関数定義は、のテンプレート特殊化です。これは、からアクセスできないがアクセス可能fcnであることを示すコンパイラエラーを生成します。A<double>::xfcn<int>A<int>::x

template<class T> class A; 

template <typename U>
typename A<U>::member_type fcn(typename A<U>::member_type);

template<class T>
class A {
    int x;
  public:
    typedef int member_type;
    friend typename A<T>::member_type fcn<T>(typename A<T>::member_type);
};

template<>
int fcn<int>(int x)
{
    A<int> i;
    A<double> d;
    i.x = 0;  // permitted
    d.x = 0;  // forbidden
    return 0;
}
于 2012-10-18T20:59:29.870 に答える
1

私はなんとかg++でそのコードをコンパイルすることができました:

template<class T> typename A<T>::member_type fcn(typename A<T>::member_type);

(したがって、2番目の「タイプ名」が必要でした)

于 2012-10-18T20:50:45.283 に答える
1

あなたは議論の中でまた言う必要がありtypenameます:

template <class T>
typename A<T>::member_type fcn(typename A<T>::member_type);
//                             ^^^^^^^^

それ以外の場合、関数テンプレートが最初にインスタンス化される前にすべてのテンプレート定義が表示される限り、コードに問題はありません。

于 2012-10-18T20:51:22.163 に答える
1

あなたの特定の例では、fcnfunction の何も実際には class に依存していないようAです。A のメソッド/フィールド、パブリック、プロテクト/プライベートのいずれにもアクセスする必要さえありません。だから意味がありません。それ以外の場合はある程度の意味がありましたが、とにかく問題を再考し、そのようなハックを必要としないよりクリーンなソリューションを考え出す価値があるようです. 深く考えた後でも必要だと思う場合は、次のようなことができます。

#include <cstdio>

template<typename T> typename T::member_type fcn(const T & v) {
    return v.value_;
}

template<class T>
class A {
  public:
    typedef T member_type;

    friend member_type fcn< A<T> >(const A<T> &);

    A() : value_(1986) {}

  private:
    T value_;
};

int main()
{
    A<int> a;
    printf("The value is: %d\n", fcn(a));
}

上記の例で注目すべき点は、相互依存関係を切り離し、 free-function が class の宣言に依存しないようにする必要があることですA。それでも結合が必要だと思われる場合は、次のコードも機能します。

#include <cstdio>

template <typename T>
class A;

template <typename T> typename A<T>::member_type fcn(const A<T> & v) {
    return v.value_;
}

template <typename T>
class A {
  public:
    typedef int member_type;

    friend member_type fcn<T>(const A<T> &);

    A() : value_(1986) {}

  private:
    member_type value_;
};

int main()
{
    A<void> a;
    printf("The value is: %d\n", fcn(a));
}

それが役に立てば幸い。幸運を!

于 2012-10-18T20:52:34.490 に答える