朋友,模板,重载<<

时间:2010-06-03 06:54:23

标签: c++ templates friend

我正在尝试使用友元函数重载<<和模板,以熟悉模板。我不知道这些编译错误是什么:

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

我也不确定为什么。有什么想法吗?感谢。

3 个答案:

答案 0 :(得分:3)

模板参数和函数参数都具有相同的名称。将其更改为:

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

标题中友元函数的声明也应该改变:

template <class G>
friend std::ostream &operator<<(std::ostream &out, const Point<G> &point);

答案 1 :(得分:1)

@Firas已经回答了你的第一个问题,所以我在此不再重复。

对于你的第二个问题,它会警告你:

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

此声明位于类模板中:

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

它告诉你,即使你可以在许多不同的类型中实例化Point,你也会说 -template operator<<是他们所有人的朋友。即,即使有一组可能无限制的Point种,你也说过只有一个 operator<<

事实上,这似乎是代码中的一个错误 - 您已将定义 operator<<作为函数模板,但声明 a(非-template)作为类的朋友(你的代码似乎没有定义的那个)。 IOW,这个定义:

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

...是一个模板,与您在上面的朋友声明中指出的相同(即使我认为您打算将它们匹配)。

答案 2 :(得分: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语法声明的类型,那么最好。

相关问题