chrono duration类型特性中可变参数省略号的用法疑问
关于检测std::chrono::duration的类型特性中省略号的疑问
我编写了一个类型特性模板,用于检测某类型是否为std::chrono::duration<Rep, Period>。我曾在推导Rep和Period的过程中卡壳许久。该方案参考了cppreference上标准类型特性的一种实现示例。我大致理解其工作原理,但对第二个test函数签名中的...存在疑惑:
- 此处的省略号是否和C语言中一样表示可变参数列表?或是在此语境下有特殊含义?
- 该省略号如何帮助区分两个
test函数?我原以为SFINAE足以匹配函数签名,但移除省略号后编译器会报歧义。
#include <chrono> #include <type_traits> namespace detail { template <typename T, typename Rep = T::rep, typename Period = T::period> std::bool_constant<std::is_same_v<T, std::chrono::duration<Rep, Period>>> test(); template <typename> std::false_type test(...); // How does `...` help here? } template <typename T> struct is_duration : decltype(detail::test<std::remove_cv<T>::type>()) {}; template <typename T> constexpr bool is_duration_v = is_duration<T>::value; static_assert(is_duration_v<std::chrono::high_resolution_clock::duration>); static_assert(is_duration_v<volatile std::chrono::microseconds>); static_assert(is_duration_v<const std::chrono::microseconds>); static_assert(!is_duration_v<double>);
补充说明(2023-07-29)
我的问题聚焦于可变参数部分,现已得到解答。若你关注通用类型特性相关内容:
- 我恢复了Howard Hinnant的回答的投票,因为它展示了第二种解决方案,对我帮助极大,相信也能帮到其他人。
- 我最终定义了一个concept:
template <typename D, typename R=D::rep, typename P=D::period> concept Duration = std::is_same_v<D, std::chrono::duration<R, P>>;
[需要说明的是,这仍然依赖duration暴露其底层类型,但该方案十分清晰。(且duration确实被文档说明会暴露这些类型。)若你不喜欢这种方式,可以使用Ted或Howard的示例创建类型特性,再基于该特性定义concept。]
基于concept的重载消除了enable-if或requires的冗余,代码更易于理解:
template <Duration T> void Overloaded(T) { std::cout << "Called with a duration.\n"; } template <std::floating_point T> void Overloaded(T) { std::cout << "Called with a floating point value.\n"; } template <typename T> void Overloaded(T) { std::cout << "Called with a something else.\n"; }
内容的提问来源于stack exchange,提问作者Adrian McCarthy
相关产品推荐
相关产品推荐

