Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call operator template?

I am feeling a bit confused about how to instantiate this template. I know it is gonna be easier to simply use friend membership to realize what I want, but what if I force to do in this way? I just wanna figure it out. (And btw, I know this template seems meaningless), I just want to make it compile.

#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;
}
like image 628
Edee Avatar asked Dec 10 '22 01:12

Edee


2 Answers

Two issues:

  1. You're declaring operator<< as template that could accept any types; which would lead to ambiguity issue with std::operator<<.

  2. You can't specify template argument explicitly when calling the operator in operator style. (You can do it in ugly function style like operator<< <Date>(std::cout, dat);) Actually you don't need to specify it, the template parameter could be deduced fine here.

You can change the code to

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

then

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

LIVE

like image 138
songyuanyao Avatar answered Dec 31 '22 14:12

songyuanyao


but what if I force to do in this way?

As others mentioned, you do not need a template here. But if you insist to do it by templates, you can apply SFINAE to the templated overload of operator<<.

(See live here)

#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;
}
like image 31
JeJo Avatar answered Dec 31 '22 16:12

JeJo