Как позвонить в шаблон оператора? - PullRequest
3 голосов
/ 27 сентября 2019

Я немного растерялся из-за того, как создать экземпляр этого шаблона.Я знаю, что будет проще использовать членство friend, чтобы понять, чего я хочу, но что, если я заставлю это сделать?Я просто хочу понять это.(И, кстати, я знаю, что этот шаблон кажется бессмысленным), я просто хочу заставить его скомпилироваться.

#include <iostream>

template <typename T>
inline std::ostream& operator<< (std::ostream& os, const T& date)
{
    os << date.getD() << " " << date.getM() << " " << date.getY() << "\n";
    return os;
}

class Date 
{
private:
    int dd, mm, yy;
public:
    Date(int d, int m, int y) : dd(d), mm(m), yy(y) {}
    int getD() const;
    int getM() const;
    int getY() const;
};

int Date::getD() const {  return dd; }

int Date::getM() const {  return mm; }

int Date::getY() const {  return yy; }

int main(int argc, char const *argv[])
{
    Date dat(1, 2, 2003);
    std::cout << <Date> dat;
    return 0;
}

Ответы [ 3 ]

6 голосов
/ 27 сентября 2019

Два вопроса:

  1. Вы объявляете operator<< как шаблон, который может принимать любые типы;что может привести к проблеме неоднозначности с std::operator<<.

  2. Вы не можете явно указать аргумент шаблона при вызове оператора в стиле operator .(Вы можете сделать это в уродливом стиле function наподобие operator<< <Date>(std::cout, dat);) На самом деле вам не нужно указывать его, параметр шаблона может быть отлично выведен здесь.

Вы можете изменить код на

std::ostream& operator<< (std::ostream& os, const Date& date) {
    os << date.getD() << " " << date.getM() << " " << date.getY() <<"\n";
    return os;
}

, затем

Date dat(1,2,2003);
std::cout << dat;

LIVE

3 голосов
/ 27 сентября 2019

но что, если я заставлю это сделать?

Как уже упоминалось, вам не нужен здесь шаблон.Но если вы настаиваете на том, чтобы сделать это с помощью шаблонов, вы можете применить SFINAE к шаблонной перегрузке operator<<.

( Смотрите в прямом эфире здесь )

#include <type_traits> // std::enable_if, std::is_same

template <typename T>
auto operator<< (std::ostream& os, const T& date)
        -> std::enable_if_t<std::is_same_v<Date, T>, std::ostream&>
{
    os << date.getD() << " " << date.getM() << " " << date.getY() << "\n";
    return os;
}
2 голосов
/ 27 сентября 2019

Это будет сделано автоматически компилятором.Просто выполните

int main(int argc, char const *argv[])
{
    Date dat(1,2,2003);
    std::cout << dat;
    return 0;
}

Это делается с ADL (поиск, зависящий от аргумента) .

...