如何实现与std::stof系列等价无开销的通用string_to_float<T>模板函数
解决方案
可以通过C++20的[[unreachable]]属性彻底解决你提到的问题,优化后的实现如下:
#include <string> #include <type_traits> template<typename T> T string_to_float(std::string const& s, std::size_t* pos = nullptr) { static_assert(std::is_same_v<T, float> || std::is_same_v<T, double> || std::is_same_v<T, long double>, "T is not a built-in floating point type"); if constexpr (std::is_same_v<T, float>) return std::stof(s, pos); if constexpr (std::is_same_v<T, double>) return std::stod(s, pos); if constexpr (std::is_same_v<T, long double>) return std::stold(s, pos); // 静态断言已保证分支完全覆盖,此处永远不会执行 [[unreachable]]; }
关键说明:
- 消除默认构造的编译错误:
[[unreachable]]会明确告知编译器这段代码永远不会被执行,因此编译器不会再去尝试检查T{}的合法性,彻底避免了误导性的编译错误。 - 保证代码生成一致性:编译器识别到
[[unreachable]]后,会完全优化掉后续的无效分支,生成的代码与直接调用std::stof/std::stod/std::stold完全一致,没有任何多余开销。 - 兼容性处理(针对C++20之前的标准):如果需要兼容旧版本C++,可以使用编译器提供的扩展替代:
// 替换原[[unreachable]]的兼容写法 #ifdef __cpp_lib_unreachable [[unreachable]]; #elif defined(__GNUC__) || defined(__clang__) __builtin_unreachable(); #elif defined(_MSC_VER) __assume(false); #else throw std::logic_error("Unreachable code reached"); #endif
静态断言已经严格限制了T的合法类型,三个if constexpr分支完全覆盖了所有合法情况,因此后续的不可达标记是绝对安全的。
内容的提问来源于stack exchange,提问作者0xbadf00d
相关产品推荐
相关产品推荐

