Skip to main content
Glama
modern_cpp.py15 kB
"""现代 C++ 建议工具""" import re from typing import List, Dict, Tuple class ModernCppSuggester: """现代 C++ 建议器""" def suggest_modern_cpp(self, code: str, target_standard: str = "cpp17") -> Tuple[List[Dict], str]: """ 建议将代码升级为现代 C++ 写法 Args: code: 要分析的 C++ 代码 target_standard: 目标标准 (cpp11, cpp14, cpp17, cpp20, cpp23) Returns: (建议列表, 格式化的建议报告) """ suggestions = [] # 根据目标标准检查可用特性 if target_standard in ['cpp11', 'cpp14', 'cpp17', 'cpp20', 'cpp23']: suggestions.extend(self._check_cpp11_features(code)) if target_standard in ['cpp14', 'cpp17', 'cpp20', 'cpp23']: suggestions.extend(self._check_cpp14_features(code)) if target_standard in ['cpp17', 'cpp20', 'cpp23']: suggestions.extend(self._check_cpp17_features(code)) if target_standard in ['cpp20', 'cpp23']: suggestions.extend(self._check_cpp20_features(code)) if target_standard == 'cpp23': suggestions.extend(self._check_cpp23_features(code)) # 生成报告 report = self._generate_report(suggestions, target_standard) return suggestions, report def _check_cpp11_features(self, code: str) -> List[Dict]: """检查可以使用 C++11 特性改进的代码""" suggestions = [] # 检查 NULL vs nullptr if re.search(r'\bNULL\b', code) or re.search(r'=\s*0\s*;.*指针', code): suggestions.append({ "standard": "C++11", "feature": "nullptr", "old_pattern": "NULL 或 0", "new_pattern": "nullptr", "example_old": "int* ptr = NULL;", "example_new": "int* ptr = nullptr;", "benefit": "类型安全,避免重载歧义" }) # 检查传统 for 循环遍历容器 if re.search(r'for\s*\(\s*\w+\s+\w+\s*=.*\.begin\(\)', code): suggestions.append({ "standard": "C++11", "feature": "范围 for 循环", "old_pattern": "for (auto it = container.begin(); ...)", "new_pattern": "for (auto& item : container)", "example_old": "for (auto it = vec.begin(); it != vec.end(); ++it) { *it... }", "example_new": "for (auto& item : vec) { item... }", "benefit": "更简洁,避免迭代器错误" }) # 检查裸指针 new if re.search(r'\bnew\s+\w+', code) and not re.search(r'make_unique|make_shared', code): suggestions.append({ "standard": "C++11", "feature": "智能指针", "old_pattern": "Type* ptr = new Type()", "new_pattern": "auto ptr = std::make_unique<Type>()", "example_old": "Widget* w = new Widget();\n// ...\ndelete w;", "example_new": "auto w = std::make_unique<Widget>();\n// 自动释放", "benefit": "自动内存管理,防止泄漏" }) # 检查 typedef vs using if re.search(r'\btypedef\s+', code): suggestions.append({ "standard": "C++11", "feature": "using 别名", "old_pattern": "typedef ... TypeName;", "new_pattern": "using TypeName = ...;", "example_old": "typedef std::vector<int> IntVec;", "example_new": "using IntVec = std::vector<int>;", "benefit": "更清晰,支持模板别名" }) # 检查虚函数重写 if re.search(r'virtual\s+\w+.*\(.*\)\s*\{', code): if not re.search(r'override\b', code): suggestions.append({ "standard": "C++11", "feature": "override 关键字", "old_pattern": "virtual void func() { ... }", "new_pattern": "void func() override { ... }", "example_old": "class Derived : public Base {\n virtual void draw() { ... }\n};", "example_new": "class Derived : public Base {\n void draw() override { ... }\n};", "benefit": "编译器检查是否正确重写" }) # 检查初始化列表 if re.search(r'\bstd::vector<\w+>\s+\w+;\s*\w+\.push_back', code): suggestions.append({ "standard": "C++11", "feature": "初始化列表", "old_pattern": "vector<int> v; v.push_back(1); v.push_back(2);", "new_pattern": "vector<int> v{1, 2};", "example_old": "std::vector<int> nums;\nnums.push_back(1);\nnums.push_back(2);", "example_new": "std::vector<int> nums{1, 2};", "benefit": "更简洁,性能更好" }) # 检查是否可以使用 auto explicit_type_pattern = re.compile(r'(\w+(?:<[^>]+>)?)\s+(\w+)\s*=\s*\1') if explicit_type_pattern.search(code): suggestions.append({ "standard": "C++11", "feature": "auto 类型推导", "old_pattern": "Type var = Type(...);", "new_pattern": "auto var = Type(...);", "example_old": "std::vector<int> vec = std::vector<int>();", "example_new": "auto vec = std::vector<int>();", "benefit": "减少冗余,提高可维护性" }) return suggestions def _check_cpp14_features(self, code: str) -> List[Dict]: """检查可以使用 C++14 特性改进的代码""" suggestions = [] # 检查是否使用了 new unique_ptr 而非 make_unique if re.search(r'unique_ptr<\w+>\(new\s+\w+', code): suggestions.append({ "standard": "C++14", "feature": "std::make_unique", "old_pattern": "std::unique_ptr<T>(new T(...))", "new_pattern": "std::make_unique<T>(...)", "example_old": "auto ptr = std::unique_ptr<Widget>(new Widget(arg));", "example_new": "auto ptr = std::make_unique<Widget>(arg);", "benefit": "更简洁,异常安全" }) # 检查 lambda 是否可以使用泛型参数 if re.search(r'\[\]\s*\(\s*\w+\s+\w+\s*\)', code): suggestions.append({ "standard": "C++14", "feature": "泛型 lambda", "old_pattern": "[](Type x) { ... }", "new_pattern": "[](auto x) { ... }", "example_old": "[](int x) { return x * 2; }", "example_new": "[](auto x) { return x * 2; }", "benefit": "更通用,代码复用" }) return suggestions def _check_cpp17_features(self, code: str) -> List[Dict]: """检查可以使用 C++17 特性改进的代码""" suggestions = [] # 检查 pair/tuple 解包 if re.search(r'\.first|\.second', code): suggestions.append({ "standard": "C++17", "feature": "结构化绑定", "old_pattern": "auto p = map.insert(...); p.first...; p.second...;", "new_pattern": "auto [it, success] = map.insert(...);", "example_old": "auto result = map.insert({key, value});\nif (result.second) { use(result.first); }", "example_new": "auto [it, inserted] = map.insert({key, value});\nif (inserted) { use(it); }", "benefit": "更清晰,避免 .first/.second" }) # 检查 if 中的临时变量 if re.search(r'auto\s+\w+\s*=.*;\s*if\s*\(\s*\w+', code): suggestions.append({ "standard": "C++17", "feature": "if 初始化语句", "old_pattern": "auto x = get(); if (x) { ... }", "new_pattern": "if (auto x = get(); x) { ... }", "example_old": "auto it = map.find(key);\nif (it != map.end()) { use(it); }", "example_new": "if (auto it = map.find(key); it != map.end()) { use(it); }", "benefit": "限制作用域,更清晰" }) # 检查是否可以使用 std::optional if re.search(r'(bool.*found|return.*nullptr)', code): suggestions.append({ "standard": "C++17", "feature": "std::optional", "old_pattern": "返回 nullptr 或布尔标志", "new_pattern": "std::optional<T>", "example_old": "int* find(int key) {\n if (...) return &value;\n return nullptr;\n}", "example_new": "std::optional<int> find(int key) {\n if (...) return value;\n return std::nullopt;\n}", "benefit": "明确表达可能不存在的值" }) # 检查字符串参数 if re.search(r'const\s+std::string\s*&', code): suggestions.append({ "standard": "C++17", "feature": "std::string_view", "old_pattern": "const std::string&", "new_pattern": "std::string_view", "example_old": "void process(const std::string& str);", "example_new": "void process(std::string_view str);", "benefit": "避免拷贝,支持多种字符串类型" }) return suggestions def _check_cpp20_features(self, code: str) -> List[Dict]: """检查可以使用 C++20 特性改进的代码""" suggestions = [] # 检查模板约束 if re.search(r'template\s*<\s*typename\s+T\s*>', code): suggestions.append({ "standard": "C++20", "feature": "Concepts", "old_pattern": "template<typename T>", "new_pattern": "template<std::integral T>", "example_old": "template<typename T>\nT add(T a, T b) { return a + b; }", "example_new": "template<std::integral T>\nT add(T a, T b) { return a + b; }", "benefit": "更清晰的错误信息,明确约束" }) # 检查手动比较运算符 if re.search(r'bool\s+operator<|bool\s+operator==', code): suggestions.append({ "standard": "C++20", "feature": "三路比较运算符 (<=>)", "old_pattern": "手动实现所有比较运算符", "new_pattern": "auto operator<=>(const T&) const = default;", "example_old": "bool operator<(const Point& p) const { ... }\nbool operator==(const Point& p) const { ... }", "example_new": "auto operator<=>(const Point&) const = default;", "benefit": "自动生成所有比较运算符" }) # 检查容器连续序列 if re.search(r'\.data\(\).*\.size\(\)', code): suggestions.append({ "standard": "C++20", "feature": "std::span", "old_pattern": "传递指针和大小", "new_pattern": "std::span<T>", "example_old": "void process(int* data, size_t size);", "example_new": "void process(std::span<int> data);", "benefit": "更安全,包含大小信息" }) return suggestions def _check_cpp23_features(self, code: str) -> List[Dict]: """检查可以使用 C++23 特性改进的代码""" suggestions = [] # 检查错误处理 if re.search(r'(throw|try|catch)', code): suggestions.append({ "standard": "C++23", "feature": "std::expected", "old_pattern": "异常或错误码", "new_pattern": "std::expected<T, Error>", "example_old": "int divide(int a, int b) {\n if (b == 0) throw std::runtime_error(\"div by 0\");\n return a / b;\n}", "example_new": "std::expected<int, Error> divide(int a, int b) {\n if (b == 0) return std::unexpected(Error::DivByZero);\n return a / b;\n}", "benefit": "明确的错误处理,避免异常开销" }) # 检查 printf 风格 if re.search(r'printf|cout\s*<<', code): suggestions.append({ "standard": "C++23", "feature": "std::print", "old_pattern": "printf 或 cout", "new_pattern": "std::print", "example_old": "std::cout << \"Hello, \" << name << \"!\" << std::endl;", "example_new": "std::print(\"Hello, {}!\\n\", name);", "benefit": "类型安全,更简洁" }) return suggestions def _generate_report(self, suggestions: List[Dict], target_standard: str) -> str: """生成格式化的建议报告""" if not suggestions: return f""" # ✅ 现代 C++ 分析报告 **目标标准**: {target_standard.upper()} **结果**: 代码已经很现代了!未发现明显的改进点。 **提示**: 继续保持使用现代 C++ 特性的好习惯! """ report = f"# 🚀 现代 C++ 升级建议\n\n" report += f"**目标标准**: {target_standard.upper()}\n" report += f"**发现**: {len(suggestions)} 个改进建议\n\n" report += "---\n\n" # 按标准分组 by_standard = {} for sug in suggestions: std = sug['standard'] if std not in by_standard: by_standard[std] = [] by_standard[std].append(sug) # 生成报告 for std in ['C++11', 'C++14', 'C++17', 'C++20', 'C++23']: if std in by_standard: report += f"## {std} 特性\n\n" for i, sug in enumerate(by_standard[std], 1): report += f"### {i}. {sug['feature']}\n\n" report += f"**旧写法**:\n```cpp\n{sug['example_old']}\n```\n\n" report += f"**新写法**:\n```cpp\n{sug['example_new']}\n```\n\n" report += f"**优势**: {sug['benefit']}\n\n" report += "---\n\n" # 总结 report += "## 💡 总结\n\n" report += f"通过采用 {target_standard.upper()} 的特性,你可以:\n" report += "- ✨ 提高代码可读性和简洁性\n" report += "- 🛡️ 增强类型安全和异常安全\n" report += "- ⚡ 提升性能(编译期优化)\n" report += "- 🔧 减少维护成本\n" return report # 全局实例 _suggester = None def get_suggester() -> ModernCppSuggester: """获取全局现代 C++ 建议器实例""" global _suggester if _suggester is None: _suggester = ModernCppSuggester() return _suggester

Implementation Reference

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SongJiangzhou/cpp_guidelines'

If you have feedback or need assistance with the MCP directory API, please join our Discord server