C++11中引入的比較常用的新特性講解(上)

目錄

1、C++11簡介

2、統一的列表初始化

2.1、{}初始化

2.2、std::initializer_list

3、變量類型推導

3.1、auto

3.2、decltype

3.3、nullptr

4、范圍for循環

5、STL中一些變化

6、右值引用和移動語義

6.1、左值引用和右值引用

6.2、右值引用使用場景和意義

6.3、完美轉發


1、C++11簡介

在2003年C++標準委員會曾經提交了一份技術勘誤表(簡稱TC1),使得C++03這個名字已經取代了C++98稱為C++11之前的最新C++標準名稱。

不過由于C++03(TC1)主要是對C++98標準中的漏洞進行修復,語言的核心部分則沒有改動,因此人們習慣性的把兩個標準合并稱為C++98 / 03標準。

從C++0x到C++11,C++標準10年磨一劍,第二個真正意義上的標準珊珊來遲。

相比于C++98 / 03,C++11則帶來了數量可觀的變化,其中包含了約140個新特性,以及對C++03標準中約600個缺陷的修正,這使得C++11更像是從C++98 / 03中孕育出的一種新語言。

相比較而言,C++11能更好地用于系統開發和庫開發、語法更加泛華和簡單化、更加穩定和安全,不僅功能更強大,而且能提升程序員的開發效率,公司實際項目開發中也用得比較多,所以要作為一個重點去學習。

C++11引入的新特性

關于C++2X最新特性的討論

查看C++各種庫說明的一個好用的網站

C++官網

小故事:
1998年是C++標準委員會成立的第一年,本來計劃以后每5年視實際需要更新一次標準,C++國際標準委員會在研究C++ 03的下一個版本的時候,一開始計劃是2007年發布,所以最初這個標準叫C++ 07。但是到06年的時候,官方覺得2007年肯定完不成C++ 07,而且官方覺得2008年可能也完不成。最后干脆叫C++ 0x。x的意思是不知道到底能在07還是08還是09年完成。結果2010年的時候也沒完成,最后在2011年終于完成了C++標準。所以最終定名為C++11。C++官網

2、統一的列表初始化

想達到的目的就是:一切都可以用列表{}初始化。

注意:列表初始化跟初始化列表(這是類的構造函數里的東西)不是一個概念。

2.1、{}初始化

在C++98中,標準允許使用花括號{}對數組或者結構體元素進行統一的列表初始值設定。

C++11擴大了用大括號括起的列表(列表初始化)的使用范圍,使其可用于所有的內置類型和用戶自定義的類型,使用列表初始化時,可添加等號(=),也可不添加。

創建對象時也可以使用列表初始化方式調用構造函數初始化。

栗子:

struct Point
{int _x;int _y;
};
class A
{
public:// explicit A(int x, int y) // explicit關鍵字,加上之后就不允許隱式類型的轉換了A(int x, int y): _x(x), _y(y){}A(int x): _x(x), _y(x){}private:int _x;int _y;
};
void test1()
{// C語言帶過來的int array1[] = {1, 2, 3, 4, 5};int array2[5] = {0};Point p = {1, 2}; // 結構體的初始化列表// C++11有的,一切都可用列表初始化int array3[5]{1};int i{1};// 單參數的隱式類型轉換A aa1 = 1;A aa2 = {1};A aa3{1};// 多參數的隱式類型轉換A aa4 = {1, 2};A aa5{3, 4};const A& aa6 = { 7,7 }; // 不加 const 是不行的,因為這中間有臨時變量,臨時變量具有常性。 // 注:這句代碼在 C++11 之后才支持
}

2.2、std::initializer_list

std::initializer_list的介紹文檔

栗子:

void test2()
{// the type of il is an initializer_listauto il = {10, 20, 30};initializer_list<int> il2 = {10, 20, 30};cout << typeid(il).name() << endl;cout << sizeof(il2) << endl; // 8/16// std::initializer_list 雖然是一個容器,但是它本身并沒有去新開空間,本質就是兩個指針,一個begin指向常量數組的開頭,一個end指向常量數組的結尾vector<int> v1;vector<int> v2(10, 1);// 隱式類型轉換vector<int> v3 = {1, 2, 3, 4, 5};vector<int> v4{10, 20, 30};// 構造vector<int> v5({10, 20, 30});// 補充:X自定義 = Y類型 --> 想要達成隱式類型轉換,則 自定義X 必須支持 Y 為參數類型的構造// 1、pair多參數隱式類型轉換// 2、initializer_list<pair>的構造map<string, string> dict = {{"sort", "排序"}, {"insert", "插入"}}; // 在沒有支持initializer_list之前,這一句代碼可是要分成三句寫的,有了initializer_list之后,就方便了很多
}

總結:當容器想用不固定的數據個數初始化時,initializer_list就派上用場了。

注:所有的容器都支持 initializer_list。

3、變量類型推導

c++11提供了多種簡化聲明的方式,尤其是在使用模板時。

3.1、auto

在C++98中auto是一個存儲類型的說明符,表明變量是局部自動存儲類型,但是局部域中定義局部的變量默認就是自動存儲類型,所以auto就沒什么價值了。

C++11中廢棄auto原來的用法,將其用于實現自動類型推斷。

這樣要求必須進行顯示初始化,讓編譯器將定義對象的類型設置為初始化值的類型。

栗子:

void test3()
{int i = 0;auto &x = i; // auto可以加引用&++x;		 // x的修改會影響iint &j = i;auto y = j; // 這里的 y 是單純的 int 還是 int& 呢?// 答:從語法層面上講 y 就是 int,也可以打開監視窗口,&y,&j,&i 看看,會發現y和j、i的地址不一樣,j、i的地址是一樣的//     j 雖然是 i 的別名(int&),但 j 的本質也是int。// 所以:這里就是一個很普通的拷貝,實際上這句代碼就等價于 auto y = i;++y;pair<string, string> kv = {"sort", "排序"};// auto [x, y] = kv; // 這是C++17支持的一種寫法(當前編譯器默認支持到C++14)
}

3.2、decltype

關鍵字decltype將變量的類型聲明為表達式指定的類型。

栗子:

template <class T>
class B
{
public:T *New(int n){return new T[n];}
};
auto func2()
{list<int> it;auto ret = it.begin();return ret;
}
auto func1()
{auto ret = func2();return ret;
}
void test4()
{list<int>::iterator it1;cout << typeid(it1).name() << endl; // typeid 是能直接拿到這個變量類型的最原始的名字(字符串)(你所看到的類型名可能是typedef過的)// typeid(it1).name() it2; // typeid 推出的只是一個單純的字符串,不能用來定義一個新的對象// decltype 可以幫你推斷出()內的變量的類型,并且你可以直接使用 decltype 推斷出的結果(類型)來定義新的變量。decltype(it1) it2; // it2和it1的類型是一樣的cout << typeid(it2).name() << endl;// 光從上面這幾句代碼,體現不出decltype的作用,因為auto也有這樣的功能,而且寫起來還更方便auto it3 = it1;cout << typeid(it3).name() << endl;auto ret = func1();// 此時如果你想要用ret的類型去實例化出一個B類型的對象,該怎么辦?(假設這里的func不只套了這么幾層,套了好多層,那你想要知道 ret 到底是什么類型,就會很麻煩)// 那么 decltype 此時就派上用場了,decltype 推斷出的結果(類型)可以用來做模板的傳參B<decltype(ret)> bb1;map<string, string> dict = { {"insert","插入"}, {"erase","刪除"} };auto it4 = dict.begin();B<decltype(it4)> bb2;B<map<string, string>::iterator> bb3; // 這句代碼可讀性更好
}

注:decltype 感覺就是跟 auto 配套使用的,用來解決一些auto搞出的問題

總結:auto 和 decltype 還是要慎用,雖然兩者都可以幫助你縮短代碼量,但是很影響可讀性。

3.3、nullptr

注:也是為了解決一些歷史遺留的問題而造出的東西。

由于C++中NULL被定義成字面量0,這樣就可能回帶來一些問題,因為0既能表示指針常量,又能表示整形常量。

所以出于清晰和安全的角度考慮,C++11中新增了nullptr,用于表示空指針。

#ifndef NULL
#ifdef __cplusplus
#define NULL ? 0
#else
#define NULL ? ((void *)0)
#endif
#endif

4、范圍for循環

栗子:

void test5()
{map<string, string> m = {{"sort", "排序"}, {"insert", "插入"}};for (auto &[x, y] : m) // 這里的auto最好加上引用&和const(無需修改就加上const),否則會有深拷貝的問題(如果有大量的string要拷貝的話,會影響程序的效率){cout << x << ":" << y << endl;// x += "1"; // map里的key是不能被修改的y += "1";}
}

5、STL中一些變化

總結:

  1. 增加的4個新容器中,也就 unordered_map、unordered_set 有點用,另外兩個(array、forward_list)沒什么屁用。
  2. 給所有容器添加了 initializer_list 構造。
  3. 給所有容器添加了 移動賦值和移動構造。
  4. 給所有容器添加了 emplace系列(與右值引用和模板的可變參數有關)。

6、右值引用和移動語義

6.1、左值引用和右值引用

傳統的C++語法中就有引用的語法,而C++11中新增了的右值引用語法特性,之前學習的引用就叫做左值引用。

無論左值引用還是右值引用,都是給對象取別名。

那么什么是左值?什么是左值引用?

左值是一個表示數據的表達式(如變量名或解引用的指針),我們可以獲取它的地址,左值可以出現在賦值符號的左邊/右邊。

而右值則不能出現在賦值符號的左邊。

左值引用就是給左值的引用,給左值取別名。

那么什么是右值?什么是右值引用?

右值也是一個表示數據的表達式,如:字面常量、表達式返回值,函數返回值(這個不能是左值引用返回)等等。

右值可以出現在賦值符號的右邊,但是不能出現出現在賦值符號的左邊,右值不能取地址。

右值引用就是對右值的引用,給右值取別名。

總之,簡單說可以取地址的就是左值,不能取地址的就是右值。

注:不能說可以修改的就是左值,不能修改的就是右值。

栗子:

const int val = 7; // 這里的 val 還是左值void test6()
{// 左值:可以取地址的int a = 10;int b = a;const int c = 10;int *p = &a;vector<int> v(10, 1);(void)v[1]; // 強轉成 void 取消警告cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << &(*p) << endl;cout << &(v[1]) << endl;// 右值:不可以取地址的// 10、string("111")、to_string(123)、x+y// cout << &10 << endl; // 字面常量// cout << &string("111") << endl; // 匿名對象// cout << &to_string(123) << endl; // 該函數的返回值返回的是一個臨時拷貝、臨時對象int x = 1, y = 2;// cout << &(x + y) << endl; // 表達式返回值// 幾個右值引用的栗子// 為了方便理解,補充兩個概念:純右值(內置類型) 將亡值(自定義類型)int &&rref1 = (x + y);			 // 純右值(內置類型)string &&rref2 = string("111");	 // 將亡值(自定義類型) // 生命周期就這一行string &&rref3 = to_string(123); // 將亡值(自定義類型) // 生命周期就這一行int &&rref4 = 10;				 // 純右值(內置類型)// 左值引用能否給右值取別名?// 答:不可以,但是 const 左值引用可以const string &ref1 = string("111");const int &ref2 = 10;// 右值引用能否給左值取別名?// 答:不可以,但是可以給 move 以后的左值取別名string s1("222");// string&& rref5 = s1;string &&rref6 = move(s1);// 補充:當需要用右值引用引用一個左值時,可以通過move函數將左值轉化為右值。//		 C++11中,std::move()函數位于 頭文件中,該函數名字具有迷惑性,它并不搬移任何東西,//		 唯一的功能就是將一個左值強制轉化為右值引用,然后實現移動語義。// 下面的s2是左值還是右值呢?string &&s2 = string("111");// 要驗證s2是左值還是右值實際上很簡單,只需要看一下能不能取的出s2的地址就好了。cout << &s2 << endl;// 總結:右值引用本身的屬性是左值!!!//       需要注意的是右值是不能取地址的,但是給右值取別名后,會導致右值被存儲到特定位置,且可以取到該位置的地址。// 下面的移動構造和移動賦值也說明了右值引用的屬性是左值。// 因為只有右值引用本身被處理成了左值,才能實現移動構造和移動賦值,才能轉移資源。-- 因為中間要 swap// 通過反匯編也是能看到右值是有地址的,只是語法上規定不能取。(沒有地址的話,右值存在哪里呢?右值也得有個地方給它存吧)// 右值引用本身是左值的意義是:為了 移動構造和移動賦值 中要 轉移資源 的語法邏輯能夠邏輯自洽。// 如果右值引用的屬性是右值,那么移動構造和移動賦值中要轉移資源的語法邏輯就是矛盾的了。// 右值是不能被改變的。(可以理解為右值帶有const屬性)// 補充:即使沒有右值引用,實際上也是有辦法能夠改變右值的// ex:string& s = (string&)string("kk"); // 強轉可以讓普通的左值引用直接引用右值// 因為不管是什么值,終歸要有空間去存儲它,有空間,不就能改了嘛。
}

6.2、右值引用使用場景和意義

前面我們可以看到左值引用既可以引用左值和又可以引用右值。

那為什么C++11還要提出右值引用呢?是不是化蛇添足呢?

下面我們來看看左值引用的短板,右值引用是如何補齊這個短板的!

首先,引用的意義是什么?

答:引用的意義就是為了減少拷貝,提高效率。

比如:

左值引用解決的場景

void function1(const string &s); // 減少傳參時的拷貝的消耗string &function2(); ? ? ? ? ? ? // 傳引用返回,減少拷貝的消耗

但是左值引用沒有徹底解決返回值的拷貝消耗問題,因為不是什么情況下都能傳引用返回的。

比如當返回值是function2中的局部對象,就不能用引用返回。

舉個栗子:

namespace kk
{class string{public:typedef char *iterator;iterator begin(){return _str;}iterator end(){return _str + _size;}string(const char *str = ""): _size(strlen(str)), _capacity(_size){cout << "string(char* str) -- 構造" << endl;_str = new char[_capacity + 1];strcpy(_str, str);}// s1.swap(s2)void swap(kk::string &s){std::swap(_str, s._str);std::swap(_size, s._size);std::swap(_capacity, s._capacity);}// 拷貝構造(左值引用)string(const kk::string &s) // 左值的拷貝構造會去調用這個: _str(nullptr){cout << "string(const string& s) -- 深拷貝" << endl;_str = new char[s._capacity + 1];strcpy(_str, s._str);_size = s._size;_capacity = s._capacity;}// 移動構造(右值引用) -- 移動將亡值的資源string(kk::string &&s) // 右值的移動(拷貝)構造會去調用這個: _str(nullptr){cout << "string(string&& s) -- 移動構造" << endl;swap(s);}// 賦值重載kk::string &operator=(const kk::string &s){cout << "string& operator=(string s) -- 深拷貝" << endl;char *tmp = new char[s._capacity + 1];strcpy(tmp, s._str);delete[] _str;_str = tmp;_size = s._size;_capacity = s._capacity;return *this;}// 移動賦值kk::string &operator=(kk::string &&s){cout << "operator=(string&& s) -- 移動賦值" << endl;swap(s);return *this;}~string(){delete[] _str;_str = nullptr;}char &operator[](size_t pos){assert(pos < _size);return _str[pos];}void reserve(size_t n){if (n > _capacity){char *tmp = new char[n + 1];strcpy(tmp, _str);delete[] _str;_str = tmp;_capacity = n;}}void push_back(char ch){if (_size >= _capacity){size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;reserve(newcapacity);}_str[_size] = ch;++_size;_str[_size] = '\0';}// string operator+=(char ch)kk::string &operator+=(char ch){push_back(ch);return *this;}const char *c_str() const{return _str;}private:char *_str = nullptr;size_t _size = 0;size_t _capacity = 0; // 不包含最后做標識的\0};kk::string to_string(int value){bool flag = true;if (value < 0){flag = false;value = 0 - value;}kk::string str;while (value > 0){int x = value % 10;value /= 10;str += ('0' + x);}if (flag == false){str += '-';}std::reverse(str.begin(), str.end());return str; // 雖然這里的str是左值,但是你加不加move,都是可以的,因為編譯器已經幫你處理好了(編譯器會強行認為這是右值),它都會去調用移動構造/移動賦值。// 注意:右值引用/這里的移動構造 并不會延長對象的生命周期,str的生命周期到了,該銷毀還是銷毀,只是發生了資源轉移。(嚴格來說,是延長了資源的生命周期)}
}

總結:右值引用徹底拯救了傳值返回所引發的效率低下的問題。一般的傳值返回需要進行 一次拷貝構造 + 一次賦值/拷貝構造 -- 拷貝構造和普通的賦值的成本很大。有了右值引用之后,傳值返回變成了 一次移動構造 + 一次移動賦值/移動構造 -- 移動構造和移動賦值只是對資源的轉移,成本很低。

舉個栗子:

vector<vector<int>> func(int rows); // 該函數 在C++11之前(右值引用出來之前) 不能這樣寫,因為效率十分的低下!!!void func(int rows, vector<vector<int>>& vv); // 該函數 在C++11之前(右值引用出來之前) 只能這樣寫,才能保證效率。

6.3、完美轉發

直接上代碼:

void Fun(int &x) { cout << "左值引用" << endl; }
void Fun(const int &x) { cout << "const 左值引用" << endl; }
void Fun(int &&x) { cout << "右值引用" << endl; }
void Fun(const int &&x) { cout << "const 右值引用" << endl; }
// std::forward 完美轉發在傳參的過程中保留對象原生類型屬性
// std::forward<T>(t)在傳參的過程中保持了t的原生類型屬性。
// 在函數模板里面,這里可以稱之為萬能引用(引用折疊)
template <typename T>
void PerfectForward(T &&t) // 注意:模板中的&&不代表右值引用,而是萬能引用,其既能接收左值又能接收右值。//		這里的 T&& 這一坨都是模板,而不只是那個T。//		這里的t的屬性根據你傳過來的參數推導。//		你傳的是左值,t就是左值,你傳的右值,t就是右值。//		你傳的 const 左值,t就是 const 左值。//		你傳的 const 右值,t就是 const 右值。
{Fun(t);					 // 如果僅僅只是這樣寫傳參的話,最后走的全是 左值引用 和 const 左值引用。-- 因為右值引用的屬性還是左值Fun(std::forward<T>(t)); // 要這樣寫,才能保證t的屬性不變,不會發生從右值退化成左值(右值引用)的情況。-- 注意不能用 move,因為這里是模板,你不知道傳過來的值本身是左值還是右值引用(右值退化成左值)?用了 move,就變成了全部都是調用 右值引用 和 const右值引用Fun((T &&)t);			 // 這樣寫的效果跟完美轉發一樣。 // 但要注意,這不是官方的寫法,不太清楚這種寫法有沒有什么缺陷。
}
void test7()
{PerfectForward(10); // 右值int a;PerfectForward(a);			  // 左值PerfectForward(std::move(a)); // 右值const int b = 8;PerfectForward(b);			  // const 左值PerfectForward(std::move(b)); // const 右值
}

總結:完美轉發的意義就是在一個既能接收左值又能接收右值的函數模板中,當需要保持一個右值引用的屬性保持不變,不想其退化成左值的時候,就用完美轉發。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/73535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/73535.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/73535.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

hugo+github pages 部署實驗室網站

&#xff01;&#xff01;太爽了&#xff0c;看了很久教程&#xff0c;自己試了好久&#xff0c;終于搞懂怎么把hugo和public單獨進行部署了&#xff01;&#xff01;&#xff01;&#xff01;&#xff01; 目的是什么&#xff1f;目的當然是為了修改這天殺的hugo的模板。現在…

兩頭文件互引問題解決(前置聲明)

問題&#xff1a; 想必正在基礎階段學習的朋友們都遇見過以下問題吧 widget.h otherwidget.h 如上問題是&#xff0c;我在widget.h中引用了otherwidget.h ,在ohterwidget中又引用了widget.h&#xff0c;兩個頭文件互相引用產生了報錯 解決辦法&#xff1a; 那么我們該如何解…

Python 異常處理完全指南

目錄 一、異常處理基礎1. 基本語法結構 二、常見異常類型1. 內置異常層次2. 常見異常示例 三、多重異常處理1. 合并捕獲2. 分層處理 四、finally與else子句1. finally 應用場景2. else 使用技巧 五、自定義異常1. 創建異常類2. 異常繼承體系 六、異常鏈與上下文1. raise from 語…

【Qt】Ubuntu22.04使用命令安裝Qt5和Qt6

1、安裝Qt5 注意:Ubuntu22.04已經沒有 qt5-default ,因此不能一鍵安裝啦 1)安裝核心組件 sudo apt install qtbase5-dev qtchooser qt5-qmake qtcreator2)安裝QtCreator sudo apt install qtcreator3)安裝工具包、Qt Quick 開發的核心庫(qtdeclarative5-dev) sudo a…

手擼一個 deepseek 數據庫對話,打造一個企業智能通訊錄(ollama + deepseek + langchain)

前言 由于 deepseek 等大語言模型數據時效性問題&#xff0c;無法跟上現實世界信息的動態變化&#xff0c;企業內部信息更是無法理解&#xff0c;為了將 deepseek 應用到企業內部&#xff0c;之前有寫過通過聯網搜索、上傳文件、搭建知識等檢索增強生成&#xff08;RAG&#xf…

線段樹SegmentTree

線段樹當中的幾個重要操作 1.PushUp 上推操作&#xff1a;由子節點算父節點的信息 p u s h u p push up pushup 操作的目的是為了維護父子節點之間的邏輯關系。當我們遞歸建樹時&#xff0c;對于每一個節點我們都需要遍歷一遍&#xff0c;并且電腦中的遞歸實際意義是先向底層…

SSH免密登錄服務器方法

Window免密連接Linux系統 生成公匙 ssh-keygen -t rsa一路回車生成公鑰 復制公匙&#xff0c;使用記事本打開復制全部內容 notepad C:\Users\DELL\.ssh\id_rsa.pub內容如"ssh-rsa AAAAB3NzaC1yc2EAAAA…" 遠程登錄服務器將內容寫入~/.ssh/authorized_keys echo …

Go 1.24 新特性解析:泛型類型別名、弱指針與終結器改進

文章精選推薦 1 JetBrains Ai assistant 編程工具讓你的工作效率翻倍 2 Extra Icons&#xff1a;JetBrains IDE的圖標增強神器 3 IDEA插件推薦-SequenceDiagram&#xff0c;自動生成時序圖 4 BashSupport Pro 這個ides插件主要是用來干嘛的 &#xff1f; 5 IDEA必裝的插件&…

MySQL 表 t1 建立聯合索引 (a, b, c),在 where a < ? and b > ? and c < ? 中哪些索引生效

文章目錄 聯合索引 abc 均范圍掃描時的索引生效情況無回表 表數據量非常少無回表 表數據量多有回表總結 聯合索引 abc 均范圍掃描時的索引生效情況 場景&#xff1a;表 t1 建立聯合索引 (a, b, c)&#xff0c;在 where a < ? and b > ? and c < ? 中哪些索引生效…

海外營收占比近4成,泡泡瑪特全球化戰略迎收獲期

3月26日&#xff0c;泡泡瑪特國際集團發布2024全年財報。財報顯示&#xff0c;2024年泡泡瑪特實現營收130.4億元&#xff08;人民幣&#xff0c;下同&#xff09;&#xff0c;同比增長106.9%&#xff0c;經調整凈利潤34.0億元&#xff0c;同比增長185.9%。中國內地營收79.7億元…

ctf-web: 不統一的解析 + sql注入要求輸入與輸出相等 -- tpctf supersqli

# 從 django.shortcuts 模塊導入 render 函數&#xff0c;用于渲染模板 from django.shortcuts import render # 從 django.db 模塊導入 connection 對象&#xff0c;用于數據庫連接 from django.db import connection# 此模塊用于創建視圖函數 # 從 django.http 模塊導入 Http…

LLM推理加速框架有哪些

LLM推理加速框架有哪些 目錄 LLM推理加速框架有哪些1. TensorRT簡介簡單使用示例2. Triton Inference Server簡介簡單使用示例3. SGLang簡介簡單使用示例4. vLLM簡介簡單使用示例1. TensorRT 簡介 TensorRT 是 NVIDIA 推出的一個用于高性能深度學習推理的 SDK。它能夠對訓練好…

【深度學習與實戰】2.1、線性回歸模型與梯度下降法先導案例--最小二乘法(向量形式求解)

為了求解損失函數 對 的導數&#xff0c;并利用最小二乘法向量形式求解 的值&#xff0c;我們按照以下步驟進行&#xff1a; ?1. 損失函數的含義? 這是?線性回歸?的平方誤差損失函數&#xff0c;目標是最小化預測值 與真實值 之間的差距。 ?定義損失函數?&#xf…

S7-1200對V90 PN進行位置控制的三種方法

S7-1200系列PLC通過PROFINET與V90 PN伺服驅動器搭配進行位置控制,實現的方法主要有以下三種: ? 方法一、在PLC中組態位置軸工藝對象,V90使用標準報文3,通過MC_Power、MC_MoveAbsolute等PLC Open標準程序塊進行控制, 這種控制方式屬于中央控制方式(位置控制在PLC中計算,驅…

愛普生FC-135晶振5G手機的極端溫度性能守護者

在5G時代&#xff0c;智能手機不僅需要高速率與低延遲&#xff0c;更需在嚴寒、酷暑、振動等復雜環境中保持穩定運行。作為 5G 手機的核心時鐘源&#xff0c;愛普生32.768kHz晶振FC-135憑借其寬溫適應性、高精度穩定性與微型化設計&#xff0c;成為5G手機核心時鐘源的理想選擇&…

ROS--IMU數據包

IMU慣性測量單元 一&#xff1a;IMU二&#xff1a;ROS中三&#xff1a;IMU數據包三&#xff1a;總結 提示&#xff1a;以下是本篇文章正文內容&#xff0c;下面案例可供參考 一&#xff1a;IMU IMU&#xff08;Inertial Measurement Unit&#xff0c;慣性測量單元&#xff09…

數據文件誤刪除,OceanBase中如何重建受影響的節點

當不慎誤刪數據文件且當前沒有現成的可替換節點時&#xff0c;在OceanBase中&#xff0c;不必急于采取極端措施&#xff0c;可以考慮運用 server_permanent_offline_time 參數&#xff0c;來重建受影響的節點。 原理&#xff1a; server_permanent_offline_time 是 OceanBase數…

Python:匹配多個字符,如何匹配開頭

匹配字符0次或無數次(*)&#xff1a; import re resre.match([A-Z][a-z]*,Lihailu) print(res.group())#提取數據 輸出結果可以全部輸出 匹配字符至少一次()&#xff1a; import re resre.match([A-Za-z]python,apython) print(res.group())#提取數據(后邊只寫python會…

Unity-RectTransform設置UI width

不知道有沒人需要這樣的代碼&#xff0c;就是.sizeDelta //不確定是不是英文翻譯的原因&#xff0c;基本很難理解&#xff0c;sizeDeltaSize&#xff0c;//未必完全正確&#xff0c;但這么寫好像總沒錯過 //image 在一個UnityEngine.UI.Image 的數組內foreach (var image in l…

java學習——函數式編程(1)

函數式編程 Java 的函數式編程是一種以函數為核心構建邏輯的編程范式,強調不可變性、聲明式代碼和無副作用的操作。它通過Lambda表達式、函數式接口(如Function、Predicate、Consumer等)和Stream API等特性實現,將計算過程抽象為函數的組合與轉換,而非傳統的命令式步驟。…