我对隐式声明和显式声明感到困惑。我不知道为什么你需要明确说出或在某些时候。例如,
在我的main.cpp
中#include <iostream>
#include "Point.h"
int main()
{
Point<int> i(5, 4);
Point<double> *j = new Point<double> (5.2, 3.3);
std::cout << i << *j;
Point<int> k;
std::cin >> k;
std::cout << k;
}
代表Point<int> k
。为什么我必须使用显式声明?否则我会收到编译错误。或者我的Point.h文件中编码不正确?
Point.h:
#ifndef POINT_H
#define POINT_H
#include <iostream>
template <class T>
class Point
{
public:
Point();
Point(T xCoordinate, T yCoordinate);
template <class G>
friend std::ostream &operator<<(std::ostream &out, const Point<G> &aPoint);
template <class G>
friend std::istream &operator>>(std::istream &in, const Point<G> &aPoint);
private:
T xCoordinate;
T yCoordinate;
};
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 G>
std::ostream &operator<<(std::ostream &out, const Point<G> &aPoint)
{
std::cout << "(" << aPoint.xCoordinate << ", " << aPoint.yCoordinate << ")";
return out;
}
template <class G>
std::istream &operator>>(std::istream &in, const Point<G> &aPoint)
{
int x, y;
std::cout << "Enter x coordinate: ";
in >> x;
std::cout << "Enter y coordinate: ";
in >> y;
Point<G>(x, y);
return in;
}
#endif
答案 0 :(得分:8)
对于类模板,必须明确指定模板参数。
对于函数模板,可以隐式推断模板参数。
Point
是一个类,因此需要明确声明。
答案 1 :(得分:2)
您的operator>>
不正确。您需要修改aPoint
:
template <class G>
std::istream &operator>>(std::istream &in, const Point<G> &aPoint)
{
std::cout << "Enter x coordinate: ";
in >> aPoint.x;
std::cout << "Enter y coordinate: ";
in >> aPoint.y;
return in;
}
此外,除了读取数据之外,operator>>
做任何事情绝对不是标准。所以下一次迭代将是:
template <class G>
std::istream &operator>>(std::istream &in, const Point<G> &aPoint)
{
in >> aPoint.x;
in >> aPoint.y;
return in;
}
这也不理想,因为输出格式与输入格式不同。
答案 2 :(得分:1)
我几乎只是在KennyTM的答案中编辑了一些额外的细节,但是到底是什么:
对于类模板,必须始终明确指定模板参数,或者将其作为默认模板参数提供。
对于函数模板,通常可以自动推断模板参数,但有时您需要(或想要)明确指定它们。对于一个相当常见的示例,请考虑以下模板:
template <class T>
void func(T const &a, T const &b) { }
如果使用两种不同类型的参数(比如int和double)调用它,并且每种类型都可以隐式转换为另一种类型,则编译器通常无法决定使用哪种类型。您可以通过使用强制转换将两个参数显式转换为相同类型,或通过显式指定模板参数来解决此问题:
func(1, 1.0); // ambiguous, T could be int or double
func((double)1, 1.0); // unambiguous
func<double>(1, 1.0); // also unambiguous