5

フレンド関数を使用して<<とテンプレートをオーバーロードし、テンプレートに慣れようとしています。これらのコンパイルエラーが何であるかわかりません:

Point.cpp:11: error:  shadows template parm 'class T'
Point.cpp:12: error: declaration of 'const Point<T>& T'

このファイルの場合

#include "Point.h"

template <class T>
Point<T>::Point() : xCoordinate(0), yCoordinate(0)
{}

template <class T>
Point<T>::Point(T xCoordinate, T yCoordinate) : xCoordinate(xCoordinate), yCoordinate(yCoordinate)
{}

template <class T>
std::ostream &operator<<(std::ostream &out, const Point<T> &T)
{
    std::cout << "(" << T.xCoordinate << ", " << T.yCoordinate << ")";
    return out;
}

私のヘッダーは次のようになります:

#ifndef POINT_H
#define POINT_H

#include <iostream>

template <class T>
class Point
{
public:
    Point();
    Point(T xCoordinate, T yCoordinate);
    friend std::ostream &operator<<(std::ostream &out, const Point<T> &T);

private:
    T xCoordinate;
    T yCoordinate;
};

#endif

私のヘッダーも警告を出します:

Point.h:12: warning: friend declaration 'std::ostream& operator<<(std::ostream&, const Point<T>&)' declares a non-template function

理由もわかりませんでした。何かご意見は?ありがとう。

4

3 に答える 3

3

テンプレートパラメータと関数パラメータはどちらも同じ名前です。次のように変更します。

template <class T>
std::ostream &operator<<(std::ostream &out, const Point<T> &point)
{
    std::cout << "(" << point.xCoordinate << ", " << point.yCoordinate << ")";
    return out;
}

ヘッダーのfriend関数の宣言も変更する必要があります。

template <class G>
friend std::ostream &operator<<(std::ostream &out, const Point<G> &point);
于 2010-06-03T06:59:19.987 に答える
1

@Firasはすでに最初の質問に回答しているので、ここでは繰り返しません。

2番目の質問では、これについて警告しています。

friend std::ostream &operator<<(std::ostream &out, const Point<T> &T);

この宣言はクラステンプレートにあります。

template <class T>
class Point { // ...

Pointこれは、さまざまなタイプをインスタンス化できる場合でも、テンプレートoperator<<はそれらすべての友達であると言っていることを示しています。つまり、さまざまな種類のsの潜在的に無制限のセットがあるとしても、それらには1つPointしかないと言っています。 operator<<

実際、これはコードの間違いのようです。関数テンプレートとして定義しましたが、(テンプレートではない)関数をクラスのフレンドとして 宣言しました(コードで定義されていないようです)。 。IOW、この定義:operator<<

template <class T>
std::ostream &operator<<(std::ostream &out, const Point<T> &T)

...これはテンプレートです。これは、上記のフレンド宣言で指摘したものとは異なります(一致させることを意図していると思いますが)。

于 2010-06-03T07:08:24.497 に答える
0

ここに微妙なエラーがあります(無関係です)。テンプレートメソッドの定義は、(通常は)呼び出し元に表示されるはずなので、ヘッダーに収めるのが最適です。

コンパイルの問題について:警告が示すように、テンプレート以外のフレンド関数を宣言しようとしています。あなたがそれを修正すれば、問題は魔法のように解決されるでしょう。

template <class T>
class Point
{
public:
  template <class U>
  friend std::ostream& operator<<(std::ostream& out, const Point<T>& p);
};

friendしかし、本当の問題は、ここで宣言が必要かどうかです。確かにxy座標は一般にアクセス可能です(少なくとも読み取り専用モードでは)?

// Free functions
template <class T>
std::ostream& operator<<(std::ostream& out, const Point<T>& p)
{
  return out << '(' << p.x() << ", " << p.y() << ')';
}

template最後に、引数の名前がスコープ内の型、特に構文を使用して宣言した型とは異なる場合が最適であることに注意してください。

于 2010-06-03T07:13:28.353 に答える