当前位置: 首页 > news >正文

C++学习:六个月从基础到就业——C++11/14:decltype关键字

C++学习:六个月从基础到就业——C++11/14:decltype关键字

本文是我C++学习之旅系列的第四十二篇技术文章,也是第三阶段"现代C++特性"的第四篇,主要介绍C++11/14中的decltype关键字。查看完整系列目录了解更多内容。

引言

在现代C++编程中,类型推导是提高代码灵活性和可读性的重要机制。上一篇文章中,我们详细介绍了auto关键字,它能根据初始化表达式自动推导变量的类型。而本文将介绍的decltype关键字则提供了一种更精确的类型推导方式,它可以在不实际计算表达式的情况下获取表达式的类型。

C++11引入decltype的主要目的是支持泛型编程中的后置返回类型,以及处理依赖于模板参数的复杂类型。C++14进一步扩展了其功能,引入了decltype(auto),简化了模板编程和完美转发。本文将详细讲解decltype的工作原理、用法以及实际应用场景,帮助你掌握这一强大的现代C++特性。

目录

  • decltype基础
    • decltype的概念与语法
    • decltype与auto的区别
  • decltype的类型推导规则
    • 标识符和成员访问表达式
    • 函数调用表达式
    • 带括号的表达式和左值表达式
    • 结合cv限定符和引用
  • decltype实际应用
    • 模板函数中的返回类型推导
    • decltype与auto结合使用
    • 带有decltype的统一初始化语法
    • 元函数中的类型计算
  • C++14中的decltype(auto)
    • 函数返回类型的使用
  • 实际应用示例
    • 示例1:通用容器访问函数
    • 示例2:泛型算法
    • 示例3:高级类型特性
  • 最佳实践与注意事项
    • 何时使用decltype
    • 避免常见陷阱
    • 风格建议
  • 总结

decltype基础

decltype的概念与语法

decltype是C++11引入的一个关键字,用于获取表达式的类型,而不实际计算表达式的值。其基本语法形式为:

decltype(expression)

decltype操作符会分析expression并返回其类型,这个过程发生在编译时,不会影响程序的运行时行为。

下面是一些基本示例:

#include <iostream>
#include <typeinfo>
#include <vector>int main() {// 基本类型int i = 42;decltype(i) j = i * 2;  // j的类型是int// 复杂表达式double d = 3.14;decltype(i + d) result = i + d;  // result的类型是double// 函数返回值类型auto func = []() -> double { return 1.0; };decltype(func()) value = 2.5;  // value的类型是double// 容器类型std::vector<int> vec = {1, 2, 3};decltype(vec) anotherVec;  // anotherVec的类型是std::vector<int>decltype(vec[0]) element = 5;  // element的类型是int&std::cout << "j = " << j << ", type: " << typeid(j).name() << std::endl;std::cout << "result = " << result << ", type: " << typeid(result).name() << std::endl;std::cout << "value = " << value << ", type: " << typeid(value).name() << std::endl;return 0;
}

decltype与auto的区别

虽然decltypeauto都涉及类型推导,但它们的推导规则和使用场景有明显区别:

  1. 推导规则

    • auto根据初始化表达式的类型进行推导,会去除引用和顶层const限定符
    • decltype根据表达式的确切类型进行推导,保留引用和const限定符
  2. 使用场景

    • auto主要用于变量声明时自动推导类型
    • decltype主要用于获取表达式类型,特别适用于模板编程和后置返回类型

下面的例子展示了两者的区别:

#include <iostream>
#include <type_traits>int main() {// auto与decltype对引用的处理不同int x = 10;int& rx = x;auto a = rx;        // a的类型是int(auto丢弃了引用)decltype(rx) b = x;  // b的类型是int&(decltype保留了引用)// auto与decltype对const的处理不同const int cx = 20;auto c = cx;           // c的类型是int(auto丢弃了顶层const)decltype(cx) d = 20;   // d的类型是const int(decltype保留了const)// 验证类型std::cout << "a is reference? " << std::boolalpha << std::is_reference<decltype(a)>::value << std::endl;  // falsestd::cout << "b is reference? " << std::boolalpha << std::is_reference<decltype(b)>::value << std::endl;  // truestd::cout << "c is const? " << std::boolalpha << std::is_const<std::remove_reference_t<decltype(c)>>::value << std::endl;  // falsestd::cout << "d is const? " << std::boolalpha << std::is_const<std::remove_reference_t<decltype(d)>>::value << std::endl;  // truereturn 0;
}

decltype的类型推导规则

decltype的类型推导规则比auto更复杂,主要有以下几点:

1. 标识符和成员访问表达式

decltype的参数是一个标识符(变量名)或者类成员访问表达式(如obj.member)时,decltype返回该标识符或成员的声明类型:

#include <iostream>
#include <type_traits>struct S {int x;double y;
};int main() {int i = 42;const int ci = i;int& ri = i;const int& cri = i;// 标识符的decltypedecltype(i) di = i;     // di的类型是intdecltype(ci) dci = ci;  // dci的类型是const intdecltype(ri) dri = i;   // dri的类型是int&decltype(cri) dcri = i; // dcri的类型是const int&// 成员访问表达式S s = {42, 3.14};decltype(s.x) dx = s.x;  // dx的类型是intdecltype(s.y) dy = s.y;  // dy的类型是doublestd::cout << "decltype(i) is int? " << std::boolalpha << std::is_same<decltype(i), int>::value << std::endl;std::cout << "decltype(ci) is const int? " << std::boolalpha << std::is_same<decltype(ci), const int>::value << std::endl;std::cout << "decltype(ri) is int&? " << std::boolalpha << std::is_same<decltype(ri), int&>::value << std::endl;return 0;
}

2. 函数调用表达式

decltype的参数是函数调用表达式时,decltype返回函数的返回类型:

#include <vector>
#include <type_traits>
#include <iostream>// 返回值为int的函数
int getInt() {return 42;
}// 返回值为引用的函数
int& getIntRef() {static int x = 42;return x;
}int main() {// 函数返回值的decltypedecltype(getInt()) i = 10;      // i的类型是intdecltype(getIntRef()) ir = i;   // ir的类型是int&// 标准库函数返回值std::vector<int> vec = {1, 2, 3};decltype(vec.size()) size = 10;    // size的类型是std::vector<int>::size_typedecltype(vec[0]) elem = vec[0];    // elem的类型是int&std::cout << "decltype(getInt()) is int? " << std::boolalpha << std::is_same<decltype(getInt()), int>::value << std::endl;std::cout << "decltype(getIntRef()) is int&? " << std::boolalpha << std::is_same<decltype(getIntRef()), int&>::value << std::endl;return 0;
}

注意:对于函数调用表达式,decltype只分析函数返回类型,不实际调用函数。

3. 带括号的表达式和左值表达式

这是decltype最复杂也最容易混淆的部分:

  • 如果表达式是一个被额外括号包围的标识符,或者是一个类左值表达式(即可以出现在赋值号左侧的表达式),那么decltype将返回该表达式的引用类型。

这条规则导致了下面这种奇怪的行为:

#include <iostream>
#include <type_traits>int main() {int x = 10;decltype(x) a = x;      // a的类型是intdecltype((x)) b = x;    // b的类型是int&,因为(x)是一个左值表达式std::cout << "decltype(x) is int? " << std::boolalpha << std::is_same<decltype(x), int>::value << std::endl;  // truestd::cout << "decltype((x)) is int&? " << std::boolalpha << std::is_same<decltype((x)), int&>::value << std::endl;  // true// 左值表达式int arr[5] = {1, 2, 3, 4, 5};decltype(arr[3]) c = arr[0];  // c的类型是int&,因为arr[3]是左值表达式// 复杂表达式int i = 10, j = 20;decltype(i = j) d = i;  // d的类型是int&,因为赋值表达式返回左值引用return 0;
}

4. 结合cv限定符和引用

decltype精确保留表达式类型的cv限定符(const和volatile)以及引用特性:

#include <iostream>
#include <type_traits>int main() {int x = 10;const int cx = 20;const int& crx = x;// 基本类型与cv限定符decltype(x) dx = x;       // dx的类型是intdecltype(cx) dcx = 20;    // dcx的类型是const intdecltype(crx) dcrx = x;   // dcrx的类型是const int&// 指针与cv限定符const int* pcx = &cx;int* const cpy = &x;decltype(pcx) dpcx = &cx; // dpcx的类型是const int*decltype(cpy) dcpy = &x;  // dcpy的类型是int* const// 验证类型std::cout << "decltype(cx) is const int? " << std::boolalpha << std::is_same<decltype(cx), const int>::value << std::endl;std::cout << "decltype(crx) is const int&? " << std::boolalpha << std::is_same<decltype(crx), const int&>::value << std::endl;std::cout << "decltype(pcx) is const int*? " << std::boolalpha << std::is_same<decltype(pcx), const int*>::value << std::endl;std::cout << "decltype(cpy) is int* const? " << std::boolalpha << std::is_same<decltype(cpy), int* const>::value << std::endl;return 0;
}

这些规则使得decltype在泛型编程中特别有用,因为它能精确地捕获表达式类型的所有细节。

decltype实际应用

模板函数中的返回类型推导

decltype最初的主要用途是推导模板函数的返回类型,特别是返回类型依赖于参数类型的情况:

#include <iostream>
#include <vector>// C++11后置返回类型语法
template<typename Container>
auto getFirstElement(Container& c) -> decltype(c[0]) {return c[0];
}int main() {std::vector<int> intVec = {1, 2, 3};std::vector<std::string> strVec = {"hello", "world"};// getFirstElement返回引用类型auto& intElem = getFirstElement(intVec);auto& strElem = getFirstElement(strVec);// 修改引用会影响原始容器intElem = 100;strElem = "modified";std::cout << "intVec[0] = " << intVec[0] << std::endl;  // 100std::cout << "strVec[0] = " << strVec[0] << std::endl;  // modifiedreturn 0;
}

在上面的例子中,decltype(c[0])会准确推导出表达式c[0]的类型,对于std::vector<int>int&,对于std::vector<std::string>std::string&

decltype与auto结合使用

在C++11中,常常需要将decltypeauto结合使用,例如为模板函数推导精确的返回类型:

#include <iostream>// 普通版本函数,无法推导类型
template<typename T, typename U>
auto multiply(T t, U u) -> decltype(t * u) {return t * u;
}// 数组版本函数,返回元素引用
template<typename T, size_t N>
auto getElement(T (&arr)[N], size_t i) -> decltype(arr[i]) {return arr[i];
}int main() {// 使用multiply函数auto result1 = multiply(5, 3.14);      // 结果是doubleauto result2 = multiply(5.0, 3);       // 结果是doublestd::cout << "5 * 3.14 = " << result1 << std::endl;std::cout << "5.0 * 3 = " << result2 << std::endl;// 使用getElement函数int arr[] = {1, 2, 3, 4, 5};auto& element = getElement(arr, 2);// 修改引用会影响原数组element = 30;std::cout << "arr[2] = " << arr[2] << std::endl;  // 输出30return 0;
}

带有decltype的统一初始化语法

C++11引入了统一初始化语法,结合decltype可以轻松地创建与已有变量相同类型的新变量:

#include <iostream>
#include <vector>
#include <complex>int main() {std::vector<int> vec1 = {1, 2, 3};decltype(vec1) vec2 = {4, 5, 6};std::complex<double> c1(1.0, 2.0);decltype(c1) c2{3.0, 4.0};std::cout << "vec2: ";for (const auto& elem : vec2) {std::cout << elem << " ";}std::cout << std::endl;std::cout << "c2: " << c2 << std::endl;return 0;
}

元函数中的类型计算

在元编程中,decltype可以用于计算类型,例如创建类型特性或模板元函数:

#include <iostream>
#include <type_traits>// 检查一个类型是否可比较
template<typename T, typename = void>
struct is_comparable : std::false_type {};template<typename T>
struct is_comparable<T, typename std::enable_if<true, decltype(std::declval<T>() == std::declval<T>(), void())>::type
> : std::true_type {};// 获取迭代器的值类型
template<typename Iterator>
struct iterator_value_type {using type = typename std::remove_reference<decltype(*std::declval<Iterator>())>::type;
};int main() {std::cout << "int is comparable: " << std::boolalpha << is_comparable<int>::value << std::endl;std::cout << "vector<int> is comparable: " << std::boolalpha << is_comparable<std::vector<int>>::value << std::endl;using it_type = std::vector<std::string>::iterator;using value_type = iterator_value_type<it_type>::type;std::cout << "vector<string>::iterator value type is string? " << std::is_same<value_type, std::string>::value << std::endl;return 0;
}

C++14中的decltype(auto)

C++14引入了decltype(auto)作为一种新的推导方式,它的工作原理是:

  1. 使用auto部分来表示我们想要类型推导
  2. 使用decltype规则而不是auto规则进行推导

这解决了C++11中使用auto无法推导引用类型和保留cv限定符的问题:

#include <iostream>
#include <vector>
#include <type_traits>// 返回一个引用的函数
int& getRef() {static int x = 42;return x;
}// C++11风格的完美转发函数
template<typename F, typename... Args>
auto perfectForward11(F&& f, Args&&... args) -> decltype(std::forward<F>(f)(std::forward<Args>(args)...)) {return std::forward<F>(f)(std::forward<Args>(args)...);
}// C++14风格的完美转发函数,更简洁
template<typename F, typename... Args>
decltype(auto) perfectForward14(F&& f, Args&&... args) {return std::forward<F>(f)(std::forward<Args>(args)...);
}int main() {int x = 10;// auto vs decltype(auto)auto a1 = x;                // intdecltype(auto) a2 = x;      // intauto a3 = (x);              // intdecltype(auto) a4 = (x);    // int&,因为(x)是左值表达式// 使用引用返回函数auto r1 = getRef();         // intdecltype(auto) r2 = getRef(); // int&// 验证类型std::cout << "a1 is reference? " << std::boolalpha << std::is_reference<decltype(a1)>::value << std::endl;  // falsestd::cout << "a2 is reference? " << std::boolalpha << std::is_reference<decltype(a2)>::value << std::endl;  // falsestd::cout << "a3 is reference? " << std::boolalpha << std::is_reference<decltype(a3)>::value << std::endl;  // falsestd::cout << "a4 is reference? " << std::boolalpha << std::is_reference<decltype(a4)>::value << std::endl;  // truestd::cout << "r1 is reference? " << std::boolalpha << std::is_reference<decltype(r1)>::value << std::endl;  // falsestd::cout << "r2 is reference? " << std::boolalpha << std::is_reference<decltype(r2)>::value << std::endl;  // true// 完美转发函数使用std::vector<int> vec = {1, 2, 3};auto& elem1 = perfectForward11(getRef, vec[0]);auto& elem2 = perfectForward14(getRef, vec[0]);elem1 = 100;elem2 = 200;std::cout << "vec[0] = " << vec[0] << std::endl;  // 200return 0;
}

decltype(auto)在泛型编程中特别有用,它能确保完美转发和函数返回类型推导时保留精确的类型特性。

函数返回类型的使用

decltype(auto)特别适合用于函数返回类型的推导,尤其是需要完美转发返回值时:

#include <iostream>
#include <vector>
#include <type_traits>template<typename Container>
decltype(auto) getFirst(Container& container) {return container[0];  // 返回容器第一个元素的精确类型(包括引用)
}template<typename T>
decltype(auto) forwardValue(T&& value) {return std::forward<T>(value);  // 完美转发,保留value的全部类型信息
}int main() {// 使用容器std::vector<int> numbers = {1, 2, 3, 4, 5};decltype(auto) first = getFirst(numbers);static_assert(std::is_same<decltype(first), int&>::value, "first should be int&");first = 100;  // 修改引用std::cout << "numbers[0] = " << numbers[0] << std::endl;  // 100// 使用转发函数int x = 42;const int cx = x;decltype(auto) rx = forwardValue(x);      // int&decltype(auto) crx = forwardValue(cx);    // const int&decltype(auto) rrx = forwardValue(10);    // int&&// 验证类型std::cout << "rx is int&? " << std::boolalpha << std::is_same<decltype(rx), int&>::value << std::endl;std::cout << "crx is const int&? " << std::boolalpha << std::is_same<decltype(crx), const int&>::value << std::endl;std::cout << "rrx is int&&? " << std::boolalpha << std::is_same<decltype(rrx), int&&>::value << std::endl;return 0;
}

这种用法在编写通用库和模板代码时非常有用,能够减少冗长的返回类型声明,同时保证类型安全。

实际应用示例

示例1:通用容器访问函数

#include <iostream>
#include <vector>
#include <map>
#include <string>// 通用的容器访问函数,正确处理返回类型(包括引用)
template<typename Container>
decltype(auto) access(Container& c, size_t index) {return c[index];
}// 特化版本,处理std::map
template<typename Key, typename Value>
Value& access(std::map<Key, Value>& m, const Key& key) {return m[key];
}int main() {// 向量示例std::vector<int> numbers = {10, 20, 30, 40, 50};// 修改元素access(numbers, 2) = 300;std::cout << "Modified vector: ";for (const auto& n : numbers) {std::cout << n << " ";}std::cout << std::endl;// 映射示例std::map<std::string, int> ages = {{"Alice", 25},{"Bob", 30},{"Charlie", 35}};// 修改或添加元素access(ages, "Alice") = 26;access(ages, "David") = 40;  // 新增元素std::cout << "Modified map:" << std::endl;for (const auto& [name, age] : ages) {std::cout << name << ": " << age << std::endl;}return 0;
}

示例2:泛型算法

#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <numeric>// 通用的求和函数,能处理不同容器和元素类型
template<typename Container>
auto sumElements(const Container& c) -> decltype(std::accumulate(std::begin(c), std::end(c), typename Container::value_type{})) {return std::accumulate(std::begin(c), std::end(c), typename Container::value_type{});
}// 获取容器中的最大元素(返回引用)
template<typename Container>
decltype(auto) getMaxElement(Container& c) {auto maxIt = std::max_element(std::begin(c), std::end(c));return *maxIt;  // 返回最大元素的引用
}int main() {std::vector<int> intVec = {1, 2, 3, 4, 5};std::list<double> doubleList = {1.1, 2.2, 3.3, 4.4, 5.5};// 求和auto intSum = sumElements(intVec);          // intauto doubleSum = sumElements(doubleList);   // doublestd::cout << "Sum of integers: " << intSum << std::endl;std::cout << "Sum of doubles: " << doubleSum << std::endl;// 获取并修改最大元素auto& maxInt = getMaxElement(intVec);auto& maxDouble = getMaxElement(doubleList);std::cout << "Max integer before: " << maxInt << std::endl;std::cout << "Max double before: " << maxDouble << std::endl;maxInt = 100;maxDouble = 100.1;std::cout << "Max integer after: " << maxInt << std::endl;std::cout << "Max double after: " << maxDouble << std::endl;// 验证修改是否生效std::cout << "Modified vector: ";for (const auto& n : intVec) {std::cout << n << " ";}std::cout << std::endl;std::cout << "Modified list: ";for (const auto& n : doubleList) {std::cout << n << " ";}std::cout << std::endl;return 0;
}

示例3:高级类型特性

#include <iostream>
#include <type_traits>
#include <vector>
#include <map>// 获取表达式的值类别(左值、右值等)
template<typename T>
struct value_category {static constexpr const char* get() {if (std::is_lvalue_reference<T>::value) {return "lvalue";} else if (std::is_rvalue_reference<T>::value) {return "rvalue";} else {return "prvalue";}}
};// 通用打印函数,显示表达式类型
template<typename T>
void printExpressionType(const char* expr, T&& value) {using ExactType = decltype(std::forward<T>(value));std::cout << "Expression: " << expr << "\n"<< "  - Type: " << typeid(std::decay_t<ExactType>).name() << "\n"<< "  - Category: " << value_category<ExactType>::get() << "\n"<< "  - Is reference? " << std::boolalpha << std::is_reference<ExactType>::value << "\n"<< "  - Is const? " << std::is_const<std::remove_reference_t<ExactType>>::value << std::endl;
}// 获取容器元素类型的通用方法
template<typename Container>
struct container_traits {using value_type = typename std::decay_t<Container>::value_type;using reference = decltype(*std::begin(std::declval<Container&>()));using iterator = decltype(std::begin(std::declval<Container&>()));
};int main() {int x = 42;const int cx = x;int& rx = x;// 分析各种表达式的类型printExpressionType("x", x);printExpressionType("cx", cx);printExpressionType("rx", rx);printExpressionType("(x)", (x));printExpressionType("std::move(x)", std::move(x));printExpressionType("42", 42);// 分析容器类型特性using VecTraits = container_traits<std::vector<int>>;using MapTraits = container_traits<std::map<std::string, double>>;std::cout << "\nVector traits:" << std::endl;std::cout << "  - value_type: " << typeid(VecTraits::value_type).name() << std::endl;std::cout << "  - reference: " << typeid(VecTraits::reference).name() << std::endl;std::cout << "  - iterator: " << typeid(VecTraits::iterator).name() << std::endl;std::cout << "\nMap traits:" << std::endl;std::cout << "  - value_type: " << typeid(MapTraits::value_type).name() << std::endl;std::cout << "  - reference: " << typeid(MapTraits::reference).name() << std::endl;std::cout << "  - iterator: " << typeid(MapTraits::iterator).name() << std::endl;return 0;
}

最佳实践与注意事项

何时使用decltype

以下是使用decltype的推荐场景:

  1. 需要精确保留类型信息,包括引用、const和volatile限定符时:

    template<typename T>
    auto getRef(T& obj) -> decltype(obj) {return obj;  // 返回精确的引用类型
    }
    
  2. 模板函数返回类型依赖于参数类型时:

    template<typename T, typename U>
    auto add(T t, U u) -> decltype(t + u) {return t + u;
    }
    
  3. 需要从表达式获取确切类型来声明变量时:

    auto func() {std::vector<int> vec = {1, 2, 3};decltype(vec[0]) elem = vec[0];  // elem的类型是int&// ...
    }
    
  4. 元编程和类型特性中需要对类型进行操作时:

    template<typename Container>
    struct element_type {using type = std::remove_reference_t<decltype(*std::begin(std::declval<Container>()))>;
    };
    

避免常见陷阱

  1. 额外括号导致的引用类型

    int x = 10;
    decltype(x) a = 20;    // a的类型是int
    decltype((x)) b = x;   // b的类型是int&,注意额外的括号!
    
  2. decltype与函数调用

    std::vector<int> getVector();
    decltype(getVector()) vec;  // 正确,vec的类型是std::vector<int>,不会调用getVector()
    decltype(getVector()[0]) elem = 10;  // 错误!getVector()[0]需要调用getVector()
    
  3. decltype与auto结合使用

    int x = 10;
    auto a = (x);       // a的类型是int
    decltype(auto) b = (x);  // b的类型是int&,注意差异!
    

风格建议

  1. 在复杂表达式上使用decltype时添加注释

    // 返回容器元素的引用类型
    template<typename Container>
    decltype(auto) getFirst(Container& c) {return c[0];
    }
    
  2. 避免对复杂嵌套表达式使用decltype,可能导致难以预测的类型:

    // 不好的做法:复杂表达式使用decltype
    decltype(foo().bar().member->func()) x;// 更好的做法:拆分为多个易于理解的步骤
    auto temp = foo().bar();
    using ResultType = decltype(temp.member->func());
    ResultType x;
    
  3. 考虑使用类型别名简化复杂类型

    template<typename Iterator>
    using value_type_t = std::remove_reference_t<decltype(*std::declval<Iterator>())>;
    

总结

decltype关键字是C++11中引入的强大类型推导工具,它允许我们在不实际计算表达式的情况下获取表达式的精确类型。与auto不同,decltype能够保留引用、const和volatile限定符,使其特别适合用于泛型编程和模板元编程。C++14引入的decltype(auto)则进一步简化了类型推导,特别是在需要完美转发和保留表达式精确类型的场景下,极大地提高了代码的灵活性和表达力。要有效使用decltypedecltype(auto),需要理解它们的类型推导规则,特别是对标识符、括号表达式和左值表达式的处理。同时,应当避免在过于复杂的表达式上使用decltype,以确保代码的可读性和可维护性。在现代C++中,decltype已经成为泛型编程和模板库开发的关键工具,与auto、类型特性和其他模板技术结合使用,可以构建出非常强大和灵活的代码。在下一篇文章中,我们将探讨C++11/14中的列表初始化特性,它如何简化对象的初始化过程,以及在现代C++编程中的广泛应用。


这是我C++学习之旅系列的第四十二篇技术文章。查看完整系列目录了解更多内容。

相关文章:

  • Redis持久化机制详解:保障数据安全的关键策略
  • 深入理解 TypeScript 中的 unknown 类型:安全处理未知数据的最佳实践
  • C语言—再学习(结构体)
  • 高频面试题(含笔试高频算法整理)基本总结回顾120
  • 3、ubantu系统 | 通过vscode远程安装并配置anaconda
  • B站锁定三倍速(自用)
  • C/C++实践(十)C语言冒泡排序深度解析:发展历史、技术方法与应用场景
  • Windows系统信息收集指南
  • python如何做数据预测
  • C++ deque双端队列、deque对象创建、deque赋值操作
  • 软件设计师教程—— 第二章 程序设计语言基础知识(上)
  • DeepSeek指令微调与强化学习对齐:从SFT到RLHF
  • 【Linux笔记】——Linux线程封装
  • Transformer 架构在目标检测中的应用:YOLO 系列模型解析
  • 进阶-数据结构部分:3、常用查找算法
  • [Windows] 系统综合优化工具 RyTuneX 1.3.1
  • 最小二乘法拟合平面(线性回归法、梯度下降、PCA法)
  • 2025年PMP 学习十七 第11章 项目风险管理 (11.1~11.4)
  • GitHub文档加载器设计与实现
  • mAP、AP50、AR50:目标检测中的核心评价指标解析
  • 浙江一教师被指殴打并威胁小学生,教育局通报涉事人被行拘
  • 南宁一学校发生伤害案件,警方通报:嫌疑人死亡,2人受伤
  • 巴菲特最新调仓:一季度大幅抛售银行股,再现保密仓位
  • 我国城市规划“全面体检”套餐出台,城市体检将逐步与供地计划等挂钩
  • 上海高院与上海妇联签协议,建立反家暴常态化联动协作机制
  • 董军同德国国防部长举行会谈