5

私はここで質問に対するlitbの回答を読んでいました。そこでは、クラステンプレートの特殊なフレンド関数を作成する方法について詳しく説明しています。

私は彼が提案したことを実行するエグザンプラを作成しようとしました(最後のコード):

// use '<>' to specialize the function template with the class template's type
friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f)

コンパイラエラーが発生します:

error: defining explicit specialization ‘operator<< <>’ in friend declaration

スペシャライゼーションでテンプレートパラメータを明示的に宣言することも機能しません。

friend std::ostream& operator<< <T>(std::ostream& os, const foo<T>& f) // same error

一方、特殊化の使用からフレンド関数テンプレートの使用に変更すると、代わりに機能ます。

template<typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works

だから私の質問は:

  • 最初のエラーの原因は何ですか?
  • ostream operator周囲のクラステンプレートの特殊化のためにを明示的に特殊化するにはどうすればよいですか?

以下の模範的なコード:

#include <iostream>

// fwd declarations
template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);

template<typename T>
struct foo
{
    foo(T val)
        : _val(val)
    {}

    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f) // error line
    //template<typename U>
    //friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
    {
        return os << "val=" << f._val;
    }

    T _val;
};


int main()
{
    foo<std::string> f("hello world");
    std::cout << f << std::endl;
    exit(0);
}
4

2 に答える 2

3

litbの例では、彼はクラスの友達として専門分野を宣言しているだけです。彼はあなたのコードがしていることである特殊化を定義していません。クラス宣言(または名前空間以外のスコープ)で特殊化を定義することは許可されていません。

必要なものは次のようなものです。

template <class T>
class foo;

template<class T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
    return os << "val=" << f._val;
}

template<typename T> 
struct foo
{
    // ...
private:
    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);
    T _val;
};
于 2012-11-19T23:26:46.910 に答える
2

2つの選択肢があります:

fwd宣言を削除し、クラス内のすべてを定義します。

template <typename U>
friend std::ostream& operator<<(std::ostream& os, const foo<U>& f) // this works
{
    return os << "val=" << f._val;
}

クラス外でフレンド関数を定義します。

template<typename T> struct foo;
template<typename T> std::ostream& operator<<(std::ostream&, const foo<T>&);

template<typename T>
struct foo
{
    foo(T val)
        : _val(val)
    {}

    friend std::ostream& operator<< <>(std::ostream& os, const foo<T>& f);

    T _val;
};

template <typename T>
std::ostream& operator<<(std::ostream& os, const foo<T>& f)
{
       return os << "val=" << f._val;
}
于 2012-11-19T23:24:32.327 に答える