lundi 13 mars 2017

How to define non-member operator overload for class template?

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?

Aucun commentaire:

Enregistrer un commentaire