实现基类自动返回派生类名称的静态成员函数:MSVC2022错误修复
修复MSVC 2022下自动获取类名的静态函数编译错误
你的代码在MSVC 2022编译失败,核心问题有三点:
std::ranges::views::split参数使用错误:你传入的是判断子范围等于空格的lambda,但针对字符序列的split应该用单个空格字符作为分隔符;transform中的参数类型不匹配:split返回的是子范围而非std::string_view&&,需要显式转换;- 未过滤
split产生的空token,可能导致后续逻辑出错。
以下是修复后的代码:
#include <ranges> #include <string_view> #include <source_location> class YourClass { public: static constexpr std::string_view ClassName() { constexpr std::string_view pretty_function = std::source_location::current().function_name(); // 修正split参数,用空格字符分隔,过滤空token,转换子范围为string_view constexpr auto tokens = pretty_function | std::ranges::views::split(' ') | std::ranges::views::transform([](auto&& token) { return std::string_view(token.begin(), token.end()); }) | std::ranges::views::filter([](std::string_view sv) { return !sv.empty() && sv != "class"; }); // 遍历token查找带模板参数的类名 for (std::string_view token : tokens) { if (size_t lt_pos = token.find('<'); lt_pos != std::string_view::npos) { return token.substr(0, lt_pos); } } // 返回最后一个有效token(非模板类名) return *std::ranges::begin(tokens); } };
关键修改说明
- 修正split分隔符:将原lambda替换为
' ',符合std::ranges::split针对字符序列的使用规则,正确按空格拆分字符串。 - 转换子范围为string_view:
split返回的子范围需要通过begin()和end()构造std::string_view,避免类型不匹配。 - 添加filter过滤无效token:直接过滤掉空字符串和"class"关键字,替代原transform中返回空string_view的逻辑,更简洁且避免后续遍历空值。
- 替换tokens.back():consteval环境下
back()可能不被MSVC支持,改用*std::ranges::begin(tokens)结合filter后的序列,确保取到有效类名。
编译时需确保项目启用C++20或更高标准(MSVC中可通过项目属性->C/C++->语言->C++标准设置)。
内容的提问来源于stack exchange,提问作者Vitaly Protasov
相关产品推荐
相关产品推荐

