最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文搞懂c++中的std::move函數(shù)

 更新時(shí)間:2022年07月09日 14:02:43   作者:CNBLOG  
這篇文章主要介紹了c++中的std::move函數(shù),在探討c++11中的Move函數(shù)前,先介紹兩個(gè)概念(左值和右值),對(duì)c++?std::move函數(shù)相關(guān)知識(shí)感興趣的朋友一起看看吧

前言

在探討c++11中的Move函數(shù)前,先介紹兩個(gè)概念(左值和右值)

左值和右值

首先區(qū)分左值和右值

左值是表達(dá)式結(jié)束后依然存在的持久對(duì)象(代表一個(gè)在內(nèi)存中占有確定位置的對(duì)象)

右值是表達(dá)式結(jié)束時(shí)不再存在的臨時(shí)對(duì)象(不在內(nèi)存中占有確定位置的表達(dá)式)

便攜方法:對(duì)表達(dá)式取地址,如果能,則為左值,否則為右值

int val;
val = 4; // 正確 ①
4 = val; // 錯(cuò)誤 ②

上述例子中,由于在之前已經(jīng)對(duì)變量val進(jìn)行了定義,故在棧上會(huì)給val分配內(nèi)存地址,運(yùn)算符=要求等號(hào)左邊是可修改的左值,4是臨時(shí)參與運(yùn)算的值,一般在寄存器上暫存,運(yùn)算結(jié)束后在寄存器上移除該值,故①是對(duì)的,②是錯(cuò)的

左值引用

右值引用

std::move函數(shù)

  • std::move作用主要可以將一個(gè)左值轉(zhuǎn)換成右值引用,從而可以調(diào)用C++11右值引用的拷貝構(gòu)造函數(shù)
  • std::move應(yīng)該是針對(duì)你的對(duì)象中有在堆上分配內(nèi)存這種情況而設(shè)置的,如下

remove_reference源碼剖析

在分析std::move()std::forward()之前,先看看remove_reference,下面是remove_reference的實(shí)現(xiàn):

template<typename _Tp>
struct remove_reference
{ typedef _Tp   type; };
 
// 特化版本
template<typename _Tp>
struct remove_reference<_Tp&>
{ typedef _Tp   type; };
 
template<typename _Tp>
struct remove_reference<_Tp&&>
{ typedef _Tp   type; };

remove_reference的作用是去除T中的引用部分,只獲取其中的類(lèi)型部分。無(wú)論T是左值還是右值,最后只獲取它的類(lèi)型部分。

std::forward源碼剖析

轉(zhuǎn)發(fā)左值

template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }

先通過(guò)獲得類(lèi)型type,定義_t為左值引用的左值變量,通過(guò)static_cast進(jìn)行強(qiáng)制轉(zhuǎn)換。_Tp&&會(huì)發(fā)生引用折疊,當(dāng)_Tp推導(dǎo)為左值引用,則折疊為_Tp& &&,即_Tp&,當(dāng)推導(dǎo)為右值引用,則為本身_Tp&&,即forward返回值與static_cast處都為_Tp&&。

轉(zhuǎn)發(fā)右值

template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
  static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
        " substituting _Tp is an lvalue reference type");
  return static_cast<_Tp&&>(__t);
}

不同于轉(zhuǎn)發(fā)左值,_t為右值引用的左值變量,除此之外中間加了一個(gè)斷言,表示當(dāng)不是左值的時(shí)候,也就是右值,才進(jìn)行static_cast轉(zhuǎn)換。

std::move()源碼剖析

// FUNCTION TEMPLATE move
template <class _Ty>
_NODISCARD constexpr remove_reference_t<_Ty>&& move(_Ty&& _Arg) noexcept { // forward _Arg as movable
    return static_cast<remove_reference_t<_Ty>&&>(_Arg);
}

std::move的功能是:

  • 傳遞的是左值,推導(dǎo)為左值引用,仍舊static_cast轉(zhuǎn)換為右值引用。
  • 傳遞的是右值,推導(dǎo)為右值引用,仍舊static_cast轉(zhuǎn)換為右值引用。
  • 在返回處,直接范圍右值引用類(lèi)型即可。還是通過(guò)renive_reference獲得_Tp類(lèi)型,然后直接type&&即可。

所以std::remove_reference<_Tp>::type&&,就是一個(gè)右值引用,我們就知道了std::move干的事情了。

小結(jié)

  • 在《Effective Modern C++》中建議:對(duì)于右值引用使用std::move,對(duì)于萬(wàn)能引用使用std::forward。
  • std::move()與std::forward()都僅僅做了類(lèi)型轉(zhuǎn)換(可理解為static_cast轉(zhuǎn)換)而已。真正的移動(dòng)操作是在移動(dòng)構(gòu)造函數(shù)或者移動(dòng)賦值操作符中發(fā)生的
  • 在類(lèi)型聲明當(dāng)中, “&&” 要不就是一個(gè) rvalue reference ,要不就是一個(gè) universal reference – 一種可以解析為lvalue reference或者rvalue reference的引用。對(duì)于某個(gè)被推導(dǎo)的類(lèi)型T,universal references 總是以 T&& 的形式出現(xiàn)。
  • 引用折疊是 會(huì)讓 universal references (其實(shí)就是一個(gè)處于引用折疊背景下的rvalue references ) 有時(shí)解析為 lvalue references 有時(shí)解析為 rvalue references 的根本機(jī)制。引用折疊只會(huì)在一些特定的可能會(huì)產(chǎn)生"引用的引用"場(chǎng)景下生效。這些場(chǎng)景包括模板類(lèi)型推導(dǎo),auto 類(lèi)型推導(dǎo), typedef 的形成和使用,以及decltype 表達(dá)式。

std::move使用場(chǎng)景

在實(shí)際場(chǎng)景中,右值引用和std::move被廣泛用于在STL和自定義類(lèi)中實(shí)現(xiàn)移動(dòng)語(yǔ)義,避免拷貝,從而提升程序性能。 在沒(méi)有右值引用之前,一個(gè)簡(jiǎn)單的數(shù)組類(lèi)通常實(shí)現(xiàn)如下,有構(gòu)造函數(shù)、拷貝構(gòu)造函數(shù)賦值運(yùn)算符重載、析構(gòu)函數(shù)等。深拷貝/淺拷貝在此不做講解。

class Array {
public:
    Array(int size) : size_(size) {
        data = new int[size_];
    }
     
    // 深拷貝構(gòu)造
    Array(const Array& temp_array) {
        size_ = temp_array.size_;
        data_ = new int[size_];
        for (int i = 0; i < size_; i ++) {
            data_[i] = temp_array.data_[i];
        }
    }
     
    // 深拷貝賦值
    Array& operator=(const Array& temp_array) {
        delete[] data_;
 
        size_ = temp_array.size_;
        data_ = new int[size_];
        for (int i = 0; i < size_; i ++) {
            data_[i] = temp_array.data_[i];
        }
    }
 
    ~Array() {
        delete[] data_;
    }
 
public:
    int *data_;
    int size_;
};

該類(lèi)的拷貝構(gòu)造函數(shù)、賦值運(yùn)算符重載函數(shù)已經(jīng)通過(guò)使用左值引用傳參來(lái)避免一次多余拷貝了,但是內(nèi)部實(shí)現(xiàn)要深拷貝,無(wú)法避免。 這時(shí),有人提出一個(gè)想法:是不是可以提供一個(gè)移動(dòng)構(gòu)造函數(shù),把被拷貝者的數(shù)據(jù)移動(dòng)過(guò)來(lái),被拷貝者后邊就不要了,這樣就可以避免深拷貝了,如:

class Array {
public:
    Array(int size) : size_(size) {
        data = new int[size_];
    }
     
    // 深拷貝構(gòu)造
    Array(const Array& temp_array) {
        ...
    }
     
    // 深拷貝賦值
    Array& operator=(const Array& temp_array) {
        ...
    }
 
    // 移動(dòng)構(gòu)造函數(shù),可以淺拷貝
    Array(const Array& temp_array, bool move) {
        data_ = temp_array.data_;
        size_ = temp_array.size_;
        // 為防止temp_array析構(gòu)時(shí)delete data,提前置空其data_      
        temp_array.data_ = nullptr;
    }
     
 
    ~Array() {
        delete [] data_;
    }
 
public:
    int *data_;
    int size_;
};

這么做有2個(gè)問(wèn)題:

  • 不優(yōu)雅,表示移動(dòng)語(yǔ)義還需要一個(gè)額外的參數(shù)(或者其他方式)。
  • 無(wú)法實(shí)現(xiàn)!temp_array是個(gè)const左值引用,無(wú)法被修改,所以temp_array.data_ = nullptr;這行會(huì)編譯不過(guò)。當(dāng)然函數(shù)參數(shù)可以改成非const:Array(Array& temp_array, bool move){...},這樣也有問(wèn)題,由于左值引用不能接右值,Array a = Array(Array(), true);這種調(diào)用方式就沒(méi)法用了。

可以發(fā)現(xiàn)左值引用真是用的很不爽,右值引用的出現(xiàn)解決了這個(gè)問(wèn)題,在STL的很多容器中,都實(shí)現(xiàn)了以右值引用為參數(shù)的移動(dòng)構(gòu)造函數(shù)移動(dòng)賦值重載函數(shù),或者其他函數(shù),最常見(jiàn)的如std::vector的push_backemplace_back。參數(shù)為左值引用意味著拷貝,為右值引用意味著移動(dòng)。

class Array {
public:
    ......
 
    // 優(yōu)雅
    Array(Array&& temp_array) {
        data_ = temp_array.data_;
        size_ = temp_array.size_;
        // 為防止temp_array析構(gòu)時(shí)delete data,提前置空其data_      
        temp_array.data_ = nullptr;
    }
public:
    int *data_;
    int size_;
};

如何使用:

// 例1:Array用法
int main(){
    Array a;
 
    // 做一些操作
    .....
     
    // 左值a,用std::move轉(zhuǎn)化為右值
    Array b(std::move(a));
}

實(shí)例:vector::push_back使用std::move提高性能

// 例2:std::vector和std::string的實(shí)際例子
int main() {
    std::string str1 = "aacasxs";
    std::vector<std::string> vec;
     
    vec.push_back(str1); // 傳統(tǒng)方法,copy
    vec.push_back(std::move(str1)); // 調(diào)用移動(dòng)語(yǔ)義的push_back方法,避免拷貝,str1會(huì)失去原有值,變成空字符串
    vec.emplace_back(std::move(str1)); // emplace_back效果相同,str1會(huì)失去原有值
    vec.emplace_back("axcsddcas"); // 當(dāng)然可以直接接右值
}
 
// std::vector方法定義
void push_back (const value_type& val);
void push_back (value_type&& val);
 
void emplace_back (Args&&... args);

在vector和string這個(gè)場(chǎng)景,加個(gè)std::move會(huì)調(diào)用到移動(dòng)語(yǔ)義函數(shù),避免了深拷貝。

除非設(shè)計(jì)不允許移動(dòng),STL類(lèi)大都支持移動(dòng)語(yǔ)義函數(shù),即可移動(dòng)的。 另外,編譯器會(huì)默認(rèn)在用戶(hù)自定義的classstruct中生成移動(dòng)語(yǔ)義函數(shù),但前提是用戶(hù)沒(méi)有主動(dòng)定義該類(lèi)的拷貝構(gòu)造等函數(shù)(具體規(guī)則自行百度哈)。 因此,可移動(dòng)對(duì)象在<需要拷貝且被拷貝者之后不再被需要>的場(chǎng)景,建議使用std::move觸發(fā)移動(dòng)語(yǔ)義,提升性能。

還有些STL類(lèi)是move-only的,比如unique_ptr,這種類(lèi)只有移動(dòng)構(gòu)造函數(shù),因此只能移動(dòng)(轉(zhuǎn)移內(nèi)部對(duì)象所有權(quán),或者叫淺拷貝),不能拷貝(深拷貝)

std::unique_ptr<A> ptr_a = std::make_unique<A>();

std::unique_ptr<A> ptr_b = std::move(ptr_a); // unique_ptr只有‘移動(dòng)賦值重載函數(shù)‘,參數(shù)是&& ,只能接右值,因此必須用std::move轉(zhuǎn)換類(lèi)型

std::unique_ptr<A> ptr_b = ptr_a; // 編譯不通過(guò)

std::move本身只做類(lèi)型轉(zhuǎn)換,對(duì)性能無(wú)影響。 我們可以在自己的類(lèi)中實(shí)現(xiàn)移動(dòng)語(yǔ)義,避免深拷貝,充分利用右值引用和std::move的語(yǔ)言特性。

std::vector<int> b(5);
b[0] = 2;
b[1] = 2;
b[2] = 2;
b[3] = 2;

// 此處用move就不會(huì)對(duì)b中已有元素重新進(jìn)行拷貝構(gòu)造然后再放到a中
std::vector<int> a = std::move(b);

將vector B賦值給另一個(gè)vector A,如果是拷貝賦值,那么顯然要對(duì)B中的每一個(gè)元素執(zhí)行一個(gè)copy操作到A,如果是移動(dòng)賦值的話,只需要將指向B的指針拷貝到A中即可,試想一下如果vector中有相當(dāng)多的元素,那是不是用move來(lái)代替copy就顯得十分高效了呢?建議看一看Scott Meyers 的Effective Modern C++,里面對(duì)移動(dòng)語(yǔ)義、右值引用以及類(lèi)型推導(dǎo)進(jìn)行了深入的探索

萬(wàn)能引用

首先,我們先看一個(gè)例子

#include <iostream>
using std::cout;
using std::endl;
template<typename T>
void func(T& param) {
    cout << param << endl;
}
int main() {
    int num = 2019;
    func(num);
    return 0;
}

這樣例子的編譯輸出不存在什么問(wèn)題,但是如果修改成下面的調(diào)用方式呢?

int main(){
    func(2019);
    return 0;
}

編譯器會(huì)產(chǎn)生錯(cuò)誤,因?yàn)樯厦娴哪0搴瘮?shù)只能接受左值或者左值引用(左值一般是有名字的變量,可以取到地址的),我們當(dāng)然可以重載一個(gè)接受右值的模板函數(shù),如下也可以達(dá)到效果

template<typename T>
void func(T& param) {
    cout << "傳入的是左值" << endl;
}
template<typename T>
void func(T&& param) {
    cout << "傳入的是右值" << endl;
}

int main() {
    int num = 2019;
    func(num);
    func(2019);
    return 0;
}

輸出結(jié)果

傳入的是左值

傳入的是右值

第一次函數(shù)調(diào)用的是左值得版本,第二次函數(shù)調(diào)用的是右值版本。但是,有沒(méi)有辦法只寫(xiě)一個(gè)模板函數(shù)即可以接收左值又可以接收右值呢?

C++11中有萬(wàn)能引用(Universal Reference)的概念:使用T&&類(lèi)型的形參既能綁定右值,又能綁定左值

但是注意了:只有發(fā)生類(lèi)型推導(dǎo)的時(shí)候,T&&才表示萬(wàn)能引用(如模板函數(shù)傳參就會(huì)經(jīng)過(guò)類(lèi)型推導(dǎo)的過(guò)程);否則,表示右值引用

所以,上面的案例我們可以修改為

template<typename T>
void func(T&& param) {
    cout << param << endl;
}
int main() {
    int num = 2019;
    func(num);
    func(2019);
    return 0;
}

引用折疊

萬(wàn)能引用說(shuō)完了,接著來(lái)聊引用折疊(Reference Collapse),因?yàn)橥昝擂D(zhuǎn)發(fā)(Perfect Forwarding)的概念涉及引用折疊。一個(gè)模板函數(shù),根據(jù)定義的形參和傳入的實(shí)參的類(lèi)型,我們可以有下面四中組合:

左值-左值 T& & # 函數(shù)定義的形參類(lèi)型是左值引用,傳入的實(shí)參是左值引用

template<typename T>
void func(T& param) {
    cout << param << endl;
}
int main(){
    int num = 2021;
    int& val = num;
    func(val);
}

左值-右值 T& && # 函數(shù)定義的形參類(lèi)型是左值引用,傳入的實(shí)參是右值引用

template<typename T>
void func(T& param) {
    cout << param << endl;
}

int main(){
    int&& val = 2021;
    func(val);
}

右值-左值 T&& & # 函數(shù)定義的形參類(lèi)型是右值引用,傳入的實(shí)參是左值引用

template<typename T>
void func(T&& param) {
    cout << param << endl;
}

int main(){
    int num = 2021;
    int& val = num;
    func(val);
}

右值-右值 T&& && # 函數(shù)定義的形參類(lèi)型是右值引用,傳入的實(shí)參是右值引用

template<typename T>
void func(T&& param) {
    cout << param << endl;
}

int main(){
    int&& val = 4;
    func(val);
}

但是C++中不允許對(duì)引用再進(jìn)行引用,對(duì)于上述情況的處理有如下的規(guī)則:

所有的折疊引用最終都代表一個(gè)引用,要么是左值引用,要么是右值引用。規(guī)則是:如果任一引用為左值引用,則結(jié)果為左值引用。否則(即兩個(gè)都是右值引用),結(jié)果才是右值引用

即就是前面三種情況代表的都是左值引用,而第四種代表的右值引用

完美轉(zhuǎn)發(fā)

下面接著說(shuō)完美轉(zhuǎn)發(fā)(Perfect Forwarding),首先,看一個(gè)例子

#include <iostream>
using std::cout;
using std::endl;
template<typename T>
void func(T& param) {
    cout << "傳入的是左值" << endl;
}
template<typename T>
void func(T&& param) {
    cout << "傳入的是右值" << endl;
}
template<typename T>
void warp(T&& param) {
    func(param);
}
int main() {
    int num = 2019;
    warp(num);
    warp(2019);
    return 0;
}

輸出的結(jié)果

傳入的是左值
傳入的是左值

是不是和預(yù)期的不一樣,下面我們來(lái)分析一下原因:

warp()函數(shù)本身的形參是一個(gè)萬(wàn)能引用,即可以接受左值又可以接受右值;第一個(gè)warp()函數(shù)調(diào)用實(shí)參是左值,所以,warp()函數(shù)中調(diào)用func()中傳入的參數(shù)也應(yīng)該是左值;第二個(gè)warp()函數(shù)調(diào)用實(shí)參是右值,根據(jù)上面所說(shuō)的引用折疊規(guī)則,warp()函數(shù)接收的參數(shù)類(lèi)型是右值引用,那么為什么卻調(diào)用了調(diào)用func()的左值版本了呢?這是因?yàn)樵?code>warp()函數(shù)內(nèi)部,右值引用類(lèi)型變?yōu)榱俗笾?,因?yàn)閰?shù)有了名稱(chēng),我們也通過(guò)變量名取得變量地址

那么問(wèn)題來(lái)了,怎么保持函數(shù)調(diào)用過(guò)程中,變量類(lèi)型的不變呢?這就是我們所謂的“變量轉(zhuǎn)發(fā)”技術(shù),在C++11中通過(guò)std::forward()函數(shù)來(lái)實(shí)現(xiàn)。我們來(lái)修改我們的warp()函數(shù)如下:

template<typename T>
void warp(T&& param) {
    func(std::forward<T>(param));
}

則可以輸出預(yù)期的結(jié)果

傳入的是左值
傳入的是右值

參考博文

現(xiàn)代C++之萬(wàn)能引用、完美轉(zhuǎn)發(fā)、引用折疊(萬(wàn)字長(zhǎng)文):https://blog.csdn.net/guangcheng0312q/article/details/103572987

C++ 中的「移動(dòng)」在內(nèi)存或者寄存器中的操作是什么,為什么就比拷貝賦值性能高呢?:https://www.zhihu.com/question/55735384

一文讀懂C++右值引用和std::move:https://zhuanlan.zhihu.com/p/335994370

到此這篇關(guān)于c++中的std::move函數(shù)的文章就介紹到這了,更多相關(guān)c++ std::move函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++中使用vector存儲(chǔ)并遍歷數(shù)據(jù)的基本步驟

    C++中使用vector存儲(chǔ)并遍歷數(shù)據(jù)的基本步驟

    C++標(biāo)準(zhǔn)模板庫(kù)(STL)提供了多種容器類(lèi)型,包括順序容器、關(guān)聯(lián)容器、無(wú)序關(guān)聯(lián)容器和容器適配器,每種容器都有其特定的用途和特性,這篇文章主要介紹了C++中使用vector存儲(chǔ)并遍歷數(shù)據(jù)的基本步驟,需要的朋友可以參考下
    2025-01-01
  • C語(yǔ)言中長(zhǎng)度為0的數(shù)組詳解

    C語(yǔ)言中長(zhǎng)度為0的數(shù)組詳解

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言中長(zhǎng)度為0的數(shù)組,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-10-10
  • C語(yǔ)言實(shí)現(xiàn)學(xué)籍管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)學(xué)籍管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)學(xué)籍管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • 關(guān)于C++11中限定作用域的枚舉類(lèi)型的問(wèn)題

    關(guān)于C++11中限定作用域的枚舉類(lèi)型的問(wèn)題

    C++中有兩種類(lèi)型的枚舉:不限定作用域的枚舉類(lèi)型和限定作用域的枚舉類(lèi)型。限定作用域的枚舉類(lèi)型是C++11標(biāo)準(zhǔn)引入的新類(lèi)型,對(duì)C++11中限定作用域的枚舉類(lèi)型相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-01-01
  • C++學(xué)習(xí)之指針的使用詳解

    C++學(xué)習(xí)之指針的使用詳解

    這篇文章主要為大家詳細(xì)介紹了C++中指針的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),對(duì)我們的學(xué)習(xí)或工作有一定的價(jià)值,感興趣的小伙伴可以了解一下
    2023-03-03
  • C++ 冒泡排序數(shù)據(jù)結(jié)構(gòu)、算法及改進(jìn)算法

    C++ 冒泡排序數(shù)據(jù)結(jié)構(gòu)、算法及改進(jìn)算法

    冒泡排序是一種簡(jiǎn)單排序。這種排序是采用“冒泡策略”將最大元素移到最右邊。在冒泡過(guò)程中,相鄰兩個(gè)元素比較,如果左邊大于右邊的,則進(jìn)行交換兩個(gè)元素。這樣一次冒泡后,可確保最大的在最右邊。然后執(zhí)行n次冒泡后排序即可完畢
    2013-04-04
  • C語(yǔ)言驅(qū)動(dòng)開(kāi)發(fā)內(nèi)核特征碼掃描PE代碼段

    C語(yǔ)言驅(qū)動(dòng)開(kāi)發(fā)內(nèi)核特征碼掃描PE代碼段

    這篇文章主要為大家介紹了C語(yǔ)言驅(qū)動(dòng)開(kāi)發(fā)內(nèi)核特征碼掃描PE代碼段,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • C++貪心算法處理多機(jī)調(diào)度問(wèn)題詳解

    C++貪心算法處理多機(jī)調(diào)度問(wèn)題詳解

    貪心算法(又稱(chēng)貪婪算法)是指,在對(duì)問(wèn)題求解時(shí),總是做出在當(dāng)前看來(lái)是最好的選擇。也就是說(shuō),不從整體最優(yōu)上加以考慮,他所做出的僅是在某種意義上的局部最優(yōu)解
    2022-06-06
  • 一文帶你深入了解C++中音頻PCM數(shù)據(jù)

    一文帶你深入了解C++中音頻PCM數(shù)據(jù)

    PCM(Pulse Code Modulation)也被稱(chēng)為脈沖編碼調(diào)制,是數(shù)字通信的編碼方式之一。這篇文章主要和大家聊聊C++中音頻PCM數(shù)據(jù)的相關(guān)操作,需要的可以參考一下
    2023-02-02
  • Qt實(shí)現(xiàn)編輯框失去焦點(diǎn)隱藏功能

    Qt實(shí)現(xiàn)編輯框失去焦點(diǎn)隱藏功能

    這篇文章主要為大家詳細(xì)介紹了Qt實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的編輯框操作——主窗口失去焦點(diǎn)隱藏功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2022-10-10

最新評(píng)論

安阳市| 和政县| 南充市| 大厂| 荣昌县| 罗平县| 句容市| 金门县| 胶南市| 临桂县| 德庆县| 瓦房店市| 且末县| 老河口市| 敖汉旗| 张北县| 油尖旺区| 云安县| 博湖县| 昭觉县| 浪卡子县| 乌鲁木齐市| 鄢陵县| 乃东县| 邵阳市| 辽宁省| 延川县| 资中县| 肇州县| 哈巴河县| 正镶白旗| 麦盖提县| 巴林右旗| 灵台县| 黄石市| 襄汾县| 永州市| 富川| 彭山县| 神池县| 高要市|