HowardHinnant / date

A date and time library based on the C++11/14/17 <chrono> header
Other
3.08k stars 669 forks source link

can't use operator<<(time_point) in operator<< of class within namespace. #756

Closed Spongman closed 1 year ago

Spongman commented 1 year ago

22ceabf

#include <iostream>
#include <chrono>
#include "date.h"

namespace NS
{
    class C {};

    std::ostream &operator<<(std::ostream &o, const C &di)
    {
        using namespace date;
        using namespace std::chrono;
        std::cout << ::std::chrono::system_clock::now();
        return o;
    }
}
<source>:8250:19: error: invalid operands to binary expression ('std::ostream' (aka 'basic_ostream<char>') and 'std::chrono::system_clock::time_point' (aka 'time_point<std::chrono::system_clock, duration<long, ratio<1, 1000000000>>>'))
        std::cout << ::std::chrono::system_clock::now();
HowardHinnant commented 1 year ago

The addition of:

 using date::operator<<;

should clear up the problem.

Spongman commented 1 year ago

thanks, that works. but how come I don't need using std::string::operator<<; to use that?

HowardHinnant commented 1 year ago

std::string::operator<< works without this treatment because std::string and its operator<< are both in namespace std. Something called "argument dependent lookup" searches namespace std because that namespace is associated with string.

Only namespace std::chrono is associated with the time_point returned from system_clock::now(). And I couldn't put it's operator<< in namespace std::chrono in this library. Instead I had to put it in namespace date. And namespace date isn't searched by "argument dependent lookup".

In C++20, the operator<< will be in namespace std::chrono along with the time_point. So this weirdness will disappear (once all std::lib vendors implement it).

Spongman commented 1 year ago

thanks for the great explanation!