当模板有 3 个时,如何在 std::chrono::duraction_cast 中只给出一个类型参数?
How is possible to give only one type parameter in std::chrono::duraction_cast while the template has 3?
当我们使用 std::chrono::duraction_cast 时,我们会这样写:
auto int_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
我们在类型参数中只给出一种类型。但是duration_cast的定义是这样的:
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);
它有三个参数。
这怎么可能?
它基于"Template Arguments Type Deduction"
这就是它的工作原理
通常我们这样做:
auto t2 = std::chrono::high_resolution_clock::now();
// some operations
auto t1 = std::chrono::high_resolution_clock::now();
// then
auto diff = t2 - t1;
t2、t1 的类型是:
std::chrono::time_point<std::chrono::high_resolution_clock>
std::chrono::time_point,本身就是一个模板class如下:
template <typename Clock, typename Duration = typename Clock::duration> time_point;
在类型 std::chrono::time_point 中,我们定义运算符-如下所示:
template<class C, class D1, class D2>
typename std::common_type<D1, D2>::type
operator- (const time_point<C,D1>& pt_lhs, const timpe_point<C,D2>& pt_rhs);
这是一个需要两个
的函数
const time_point<C,D>&
和 returns 类型的变量:
std::common_type<D1, D2>::type
两个持续时间之间的共同类型是持续时间本身,即operator- returns 类型的变量
template <class Rep, class Period = std::ratio<1>> class duration;
因此 t2 - t1 的类型是:
decltype(t2 - t1) = class duration <class Rep, class Period = std::ratio<1>>
// <- pseudo code, you cannot write this in C++.
所以,函数的模板参数之一
std::chrono::duration_cast<class ToDuration, class Rep, class Period>
已经被默认值定义
class Period = std::ratio<1>
这个函数的第一个参数由函数本身的参数定义:
class ToDuration = decltype(std::chrono::milliseconds);
我们需要推导出函数 duration_cast 的第二个模板参数,我们完成了。
class Rep = decltype(?)
我们再次从 运算符- 结果的 return 类型推导出它,即
decltype(t2 -t1) = template <typename Rep?, class Period = std::ratio<1>>
如果你查看模板的文档 class duration 你会发现 class Rep 是实现已定义(依赖于 STL 库的实现者。即 WindowsOS、LinuxOs、MacOs...)并且它是整数或浮点数(算术类型)
完成!!!
所有 3 个模板参数现在都为编译器所熟知:
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);
// with
// class ToDuration = std::chrono::milliseconds
// class Rep = arithmetic type relying on the implementation deduced from
the return value of std::chrono::high_resolution_clock::now()
// class Period = std::ratio<1> by default and it can be something else
like std::ratio<0.001> for exple
就是这样,它背后没有魔法,永远不要满足于这种答案:"IT'S COMPILER MAGIC"没有魔法这样的东西,即使是魔法也可以用科学来解释。 ;)
祝你好运。
当我们使用 std::chrono::duraction_cast 时,我们会这样写:
auto int_ms = std::chrono::duration_cast<std::chrono::milliseconds>(t2 - t1);
我们在类型参数中只给出一种类型。但是duration_cast的定义是这样的:
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);
它有三个参数。
这怎么可能?
它基于"Template Arguments Type Deduction"
这就是它的工作原理
通常我们这样做:
auto t2 = std::chrono::high_resolution_clock::now();
// some operations
auto t1 = std::chrono::high_resolution_clock::now();
// then
auto diff = t2 - t1;
t2、t1 的类型是:
std::chrono::time_point<std::chrono::high_resolution_clock>
std::chrono::time_point,本身就是一个模板class如下:
template <typename Clock, typename Duration = typename Clock::duration> time_point;
在类型 std::chrono::time_point 中,我们定义运算符-如下所示:
template<class C, class D1, class D2>
typename std::common_type<D1, D2>::type
operator- (const time_point<C,D1>& pt_lhs, const timpe_point<C,D2>& pt_rhs);
这是一个需要两个
的函数const time_point<C,D>&
和 returns 类型的变量:
std::common_type<D1, D2>::type
两个持续时间之间的共同类型是持续时间本身,即operator- returns 类型的变量
template <class Rep, class Period = std::ratio<1>> class duration;
因此 t2 - t1 的类型是:
decltype(t2 - t1) = class duration <class Rep, class Period = std::ratio<1>>
// <- pseudo code, you cannot write this in C++.
所以,函数的模板参数之一
std::chrono::duration_cast<class ToDuration, class Rep, class Period>
已经被默认值定义
class Period = std::ratio<1>
这个函数的第一个参数由函数本身的参数定义:
class ToDuration = decltype(std::chrono::milliseconds);
我们需要推导出函数 duration_cast 的第二个模板参数,我们完成了。
class Rep = decltype(?)
我们再次从 运算符- 结果的 return 类型推导出它,即
decltype(t2 -t1) = template <typename Rep?, class Period = std::ratio<1>>
如果你查看模板的文档 class duration 你会发现 class Rep 是实现已定义(依赖于 STL 库的实现者。即 WindowsOS、LinuxOs、MacOs...)并且它是整数或浮点数(算术类型)
完成!!!
所有 3 个模板参数现在都为编译器所熟知:
template <class ToDuration, class Rep, class Period>
constexpr ToDuration duration_cast(const duration<Rep,Period>& d);
// with
// class ToDuration = std::chrono::milliseconds
// class Rep = arithmetic type relying on the implementation deduced from
the return value of std::chrono::high_resolution_clock::now()
// class Period = std::ratio<1> by default and it can be something else
like std::ratio<0.001> for exple
就是这样,它背后没有魔法,永远不要满足于这种答案:"IT'S COMPILER MAGIC"没有魔法这样的东西,即使是魔法也可以用科学来解释。 ;)
祝你好运。