Путать с неявными и явными объявлениями шаблонов - PullRequest
0 голосов
/ 04 июня 2010

Я путаюсь с неявными и явными объявлениями. Я не знаю, почему вы должны явно сказать или в определенное время. Например,

В моем 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

Ответы [ 3 ]

8 голосов
/ 04 июня 2010

Для шаблона класса аргументы шаблона должны быть указаны явно.

Для шаблона функции аргументы шаблона могут быть выведены неявно.

Point - это класс, поэтому требуется явное объявление.

2 голосов
/ 04 июня 2010

Ваш 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;
}

Это также не идеально, поскольку формат вывода отличается от формата ввода.

1 голос
/ 04 июня 2010

Я почти только отредактировал пару дополнительных деталей в ответе 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...