C++能否在concepts中指定模板类?适配std::chrono::duration转换方法
实现方案
两种实现都保留原有接口使用习惯,非duration类型的转换逻辑不受影响。
方法1:使用C++20 Concepts实现
首先定义duration类型的约束concept,通过检查嵌套类型+模板匹配双重校验,避免误匹配其他自定义类型:
#include <chrono> #include <string> #include <type_traits> #include <boost/lexical_cast.hpp> // 约束:仅匹配std::chrono::duration的实例化类型 template<typename T> concept is_chrono_duration = requires { typename T::rep; typename T::period; } && std::is_same_v<T, std::chrono::duration<typename T::rep, typename T::period>>; // 原逻辑:非duration类型走boost原生转换 template<class T> T to_t(const std::string& str) requires (!is_chrono_duration<T>) { return boost::lexical_cast<T>(str); } // 新增逻辑:duration类型单独处理 template<is_chrono_duration T> T to_t(const std::string& str) { // 自动适配duration的底层数值类型(整型/浮点型都支持) auto num = boost::lexical_cast<typename T::rep>(str); return T{num}; }
使用示例:
#include <iostream> int main() { auto sec = to_t<std::chrono::seconds>("1234"); std::cout << sec.count() << "s\n"; // 输出 1234s auto ns = to_t<std::chrono::nanoseconds>("5678"); std::cout << ns.count() << "ns\n"; // 输出 5678ns // 原有转换逻辑正常可用 int int_val = to_t<int>("999"); double double_val = to_t<double>("3.14"); return 0; }
方法2:C++11及以上兼容方案(无Concept)
如果编译器不支持C++20,用SFINAE实现相同能力:
#include <chrono> #include <string> #include <type_traits> #include <boost/lexical_cast.hpp> // 类型萃取判断是否为duration template<typename T> struct is_chrono_duration : std::false_type {}; template<typename Rep, typename Period> struct is_chrono_duration<std::chrono::duration<Rep, Period>> : std::true_type {}; // 非duration版本 template<class T> typename std::enable_if<!is_chrono_duration<T>::value, T>::type to_t(const std::string& str) { return boost::lexical_cast<T>(str); } // duration版本 template<class T> typename std::enable_if<is_chrono_duration<T>::value, T>::type to_t(const std::string& str) { auto num = boost::lexical_cast<typename T::rep>(str); return T{num}; }
内容的提问来源于stack exchange,提问作者assassin5615
相关产品推荐
相关产品推荐

