I have a class template that has a constructor taking an std::chrono::duration, because I want to be able to use the chrono_literals to construct it. Now, I'm trying to define a non-member operator overload but I can't get it to work with the duration constructor:
#include <chrono>
#include <iostream>
using namespace std;
template <int n> struct MyClass {
MyClass() = default;
template <typename REP, typename PERIOD>
constexpr MyClass(const std::chrono::duration<REP, PERIOD> &d) noexcept
: num(d.count()) {}
int num = n;
};
template <int n> bool operator==(MyClass<n> lhs, MyClass<n> rhs) {
return lhs.num == rhs.num;
}
int main(int argc, char *argv[]) {
using namespace std::literals::chrono_literals;
MyClass<0> m1(10ns);
if (m1 == 10ns)
cout << "Yay!" << endl;
return 0;
}
gcc is giving this error for rejecting my overload:
main.cpp:34:12: error: no match for ‘operator==’ (operand types are ‘MyClass<0>’ and ‘std::chrono::nanoseconds {aka std::chrono::duration<long int, std::ratio<1l, 1000000000l> >}’)
if (m1 == 10ns)
~~~^~~~~~~
main.cpp:23:6: note: candidate: template<int n> bool operator==(MyClass<n>, MyClass<n>)
bool operator == (MyClass<n> lhs, MyClass<n> rhs)
^~~~~~~~
main.cpp:23:6: note: template argument deduction/substitution failed:
main.cpp:34:15: note: ‘std::chrono::duration<long int, std::ratio<1l, 1000000000l> >’ is not derived from ‘MyClass<n>’
if (m1 == 10ns)
^~~~
Is there any way to make this work?
Operator overloading of non-member function or friend function. A non-member function does not have access to the private data of that class. This means that an operator overloading function must be made a friend function if it requires access to the private members of the class.
A template function can be overloaded either by a non-template function or using an ordinary function template.
Member functions of class templates (C++ only) You may define a template member function outside of its class template definition. The overloaded addition operator has been defined outside of class X . The statement a + 'z' is equivalent to a. operator+('z') .
You may overload a function template either by a non-template function or by another function template. The function call f(1, 2) could match the argument types of both the template function and the non-template function.
The simpler way is to put the function in the class:
template <int n> struct MyClass {
MyClass() = default;
template <typename REP, typename PERIOD>
constexpr MyClass(const std::chrono::duration<REP, PERIOD> &d) noexcept
: num(d.count()) {}
friend bool operator==(MyClass lhs, MyClass rhs) { return lhs.num == rhs.num; }
int num = n;
};
Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With