我有一个类模板,其构造函数采用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)
^~~~
有没有办法让这项工作?
答案 0 :(得分:10)
更简单的方法是将函数放在类中:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Antlr" version="3.4.1.9004" targetFramework="net452" />
<package id="bootstrap" version="3.3.2" targetFramework="net452" />
...
答案 1 :(得分:8)
这不起作用:
if (m1 == 10ns)
因为我们在operator==
和MyClass<0>
之间对std::chrono::duration<???, std::nano>
进行查询时,我们找到的唯一运营商是:
template <int n>
bool operator==(MyClass<n> lhs, MyClass<n> rhs);
这不是匹配 - 10ns
不是任何MyClass<n>
的{{1}},因此模板扣除失败。要编写非成员相等运算符,您需要匹配任何持续时间:
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> );
声明为非会员朋友,Jarod42建议。这样做的原因是,当你的非成员函数是一个函数模板时,朋友不是。因此operator==
上的查找找到了函数:
m1 == 10ns
bool operator==(MyClass<0>, MyClass<0>);
可转换为10ns
,这在此上下文中是允许的,因此可行。转换非常便宜,所以不用担心。而你只需编写一个函数。