[英]How to define non-member operator overload for class template?
我有一個類模板,其構造函數采用std :: chrono :: duration,因為我希望能夠使用chrono_literals來構造它。 現在,我正在嘗試定義非成員運算符重載,但我無法使用持續時間構造函數:
#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拒絕我的重載就是這個錯誤:
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)
^~~~
有沒有辦法讓這項工作?
更簡單的方法是將函數放在類中:
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;
};
這不起作用:
if (m1 == 10ns)
因為當我們在MyClass<0>
和std::chrono::duration<???, std::nano>
之間查詢operator==
,我們找到的唯一運算符是:
template <int n>
bool operator==(MyClass<n> lhs, MyClass<n> rhs);
這不是匹配 - 對於任何n
, 10ns
不是MyClass<n>
,因此模板推斷失敗。 要編寫非成員相等運算符,您需要匹配任何持續時間:
template <int n, class R, class P> bool operator==(MyClass<n>, duration<R,P> );
在兩個方向:
template <int n, class R, class P> bool operator==(duration<R,P>, MyClass<n> );
除了您已經擁有的運營商。 這會奏效,有時甚至是必要的。
一種更簡單的方法是將operator==
聲明為非成員朋友,就像Jarod42建議的那樣。 這個工作的原因是你的非成員函數是一個函數模板,朋友不是 。 因此在m1 == 10ns
查找找到函數:
bool operator==(MyClass<0>, MyClass<0>);
10ns
可以轉換為MyClass<0>
,這在此上下文中是允許的,因此這是有效的。 轉換非常便宜,所以不用擔心。 而你只需編寫一個函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.