色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Modern C++ 有哪些能真正提升開發效率的語法糖

Linux愛好者 ? 來源:程序員小方 ? 作者: 張小方 ? 2021-11-09 11:00 ? 次閱讀

我們說的 Modern C++,一般指的是 C++11 及以后的標準,從 C++ 11 開始,Modern C++ 引入了大量的實用的特性,主要是兩大方面,學習的時候也可以從這兩大方面學習:

  1. 增強或者改善的語法特性;

  2. 新增的或者改善的 STL 庫。

我們來看幾個具體的案例:

案例 1:統一的類成員初始化語法與 std::initializer_list

在 C++98/03 中,假設我們要初始化一個類數組類型的成員(例如常用的清零操作),我們需要這么寫:

classA
{
public:
A()
{
//初始化arr
arr[0]=0;
arr[1]=0;
arr[2]=0;
arr[3]=0;
}

public:
intarr[4];
};

假設數組 arr 較長,我們可以使用循環或者借助 memset 函數去初始化,代碼如下:

classA
{
public:
A()
{
//使用循環初始化arr
for(inti=0;iA()
{
//使用memset初始化arr
memset(arr,0,sizeof(arr));
}

public:
intarr[4];
};

但是,我們知道,在 C++98/08 中我們可以直接通過賦值操作來初始化一個數組的:

intarr[4]={0};

但是對于作為類的成員變量的數組元素,C++98/03 是不允許我們這么做的。到 C++11 中全部放開并統一了,在 C++11 中我們也可以使用這樣的語法是初始化數組:

classA
{
public:
//在C++11中可以使用大括號語法初始化數組類型的成員變量
A():arr{0}
{
}

public:
intarr[4];
};

如果你有興趣,我們可以更進一步:在 C++ 98/03 標準中,對類的成員必須使用 static const 修飾,而且類型必須是整型 (包括 bool、 char、 int、 long 等),這樣才能使用這種初始化語法:

//C++98/03在類定義處初始化成員變量
classA
{
public:
//T的類型必須是整型,且必須使用staticconst修飾
staticconstTt=某個整型值;
};

在 C++11 標準中就沒有這種限制了,我們可以使用花括號(即{})對任意類型的變 量進行初始化,而且不用是 static 類型:

//C++11在類定義處初始化成員變量
classA
{
public:
//有沒有一種Java初始化類成員變量的即視感^_^
boolma{true};
intmb{2019};
std::stringmc{"helloworld"};
};

當然,在實際開發中,建議還是將這些成員變量的初始化統一寫到構造函數的初始化列表中,方便閱讀和維護代碼。

案例 2:注解標簽

C++ 14 引入了[[deprecated]]標簽來表示一個函數或者類型等已被棄用,在使用這些被棄用的函數或者類型并編譯時, 編譯器會給出相應的警告, 有的編譯器直接生成編譯錯誤:

[[deprecated]]voidfuncX();

這個標簽在實際開發中非常有用,尤其在設計一些庫代碼時,如果庫作者希望某個函數或者類型不想再被用戶使用,則可以使用該標注標記。當然,我們也可以使用如下語法給出編譯時的具體警告或者出錯信息

[[deprecated("usefunYinstead")]]voidfuncX();

有如下代碼:

#include
[[deprecated("usefuncYinstead")]]voidfuncX()
{
//實現省略
}

intmain()
{
funcX();
return0;
}

若在 main 函數中調用被標記為 deprecated 的函數 funcX,則在 gcc/g++7.3 中編譯時會得到如下警告信息:

[root@myaliyuntestmybook]#g++-g-otest_attributestest_attributes.cpp
test_attributes.cpp:Infunction‘intmain()’:
test_attributes.cpp11:warning:‘voidfuncX()’isdeprecated:usefuncYinstead
[-Wdeprecated-declarations]
funcX();
^
test_attributes.cpp42:note:declaredhere
[[deprecated("usefuncYinstead")]]voidfuncX()

Java 開發者對這個標注應該再熟悉不過了。在 Java 中使用@Deprecated 標注可以達到同樣的效果,這大概是 C++標準委員“拖欠”廣大 C++開發者太久的一個特性吧。

C++ 17 提供了三個實用注解:[[fallthrough]]、[[nodiscard]]和[[maybe_unused]],這里 逐一介紹它們的用法。[[fallthrough]]用于 switch-case 語句中,在某個 case 分支執行完畢后如果沒有 break 語句,則編譯器可能會給出一條警告。但有時這可能是開發者有意為之的。為了讓編譯器明確知道開發者的意圖,可以在需要某個 case 分支被“貫穿”的地方(上一個 case 沒有break 語句)顯式設置 [[fallthrough]] 標記。代碼示例如下:

switch(type)
{
case1:
func1();
//這個位置缺少break語句,且沒有fallthrough標注,
//可能是一個邏輯錯誤,在編譯時編譯器可能會給出警告,以提醒修改

case2:
func2();
//這里也缺少break語句,但是使用了fallthrough標注,
//說明是開發者有意為之的,編譯器不會給出任何警告
[[fallthrough]];

case3:
func3();
}

注意:在 gcc/g++中, [[fallthrough]] 后面的分號不是必需的,在 Visual Studio 中必須加上分號,否則無法編譯通過。

熟悉 Golang 的讀者,可能對 fallthrough 這一語法特性非常熟悉, Golang 中在 switch-case 后加上 fallthrough,是一個常用的告訴編譯器意圖的語法規則。代碼示例如下:

//以下是Golang語法
s:="abcd"
switchs[3]{
case'a':
fmt.Println("Theintegerwas<=?4")
fallthrough

case'b':
fmt.Println("Theintegerwas<=?5")
fallthrough

case'c':
fmt.Println("Theintegerwas<=?6")

default:
fmt.Println("defaultcase")
}

[[nodiscard]]一般用于修飾函數,告訴函數調用者必須關注該函數的返回值(即不能丟棄該函數的返回值)。如果函數調用者未將該函數的返回值賦值給一個變量,則編譯器會給出一個警告。例如,假設有一個網絡連接函數 connect,我們通過返回值明確說明了連接是否建立成功,則為了防止調用者在使用時直接將該值丟棄,我們可以將該函數使用[[nodiscard]]標記:

[[nodiscard]]intconnect(constchar*address,shortport)
{
//實現省略
}

intmain()
{
//忽略了connect函數的返回值,編譯器會給出一個警告
connect("127.0.0.1",8888);
return0;
}

在 C++ 20 中,對于諸如 operator new()、 std::allocate()等庫函數均使用了 [[nodiscard]] 進行標記,以強調必須使用這些函數的返回值。再來看另外一個標記。在通常情況下,編譯器會對程序代碼中未使用的函數或變量給出警告,另一些編譯器干脆不允許通過編譯。在 C++ 17 之前,程序員為了消除這些未使用的變量帶來的編譯警告或者錯誤,要么修改編譯器的警告選項設置,要么定義一個類似于 UNREFERENCED_PARAMETER 的宏來顯式調用這些未使用的變量一次,以消除編譯警告或錯誤:

#defineUNREFERENCED_PARAMETER(x)x

intAPIENTRYwWinMain(HINSTANCEhInstance,HINSTANCEhPrevInstance,LPWSTRlpCmdLine,intnCmdShow)
{
//C++17之前為了消除編譯器對未使用的變量hPrevInstance、lpCmdLine給出的警告,我們可以這么做
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
//無關代碼省略
}

以上代碼節選自一個標準 Win32 程序的結構,其中的函數參數 hPrevInstance 和 lpCmdLine 一般不會被用到,編譯器會給出警告。為了消除這類警告,這里定義了一個宏 UNREFERENCED_PARAMETER 并進行調用,造成這兩個參數被使用的假象。C++17 有了 [[maybe_unused]] 注解之后,我們就再也不需要這類宏來“欺騙”編譯器了。以上代碼使用該注解后可以修改如下:

intAPIENTRYwWinMain(HINSTANCEhInstance,
[[maybe_unused]]HINSTANCEhPrevInstance,
[[maybe_unused]]LPWSTRlpCmdLine,
intnCmdShow)
{
//無關代碼省略
}

案例 3:final、 override 關鍵字和 =default、 =delete 語法

3.1 final 關鍵字

在 C++11 之前,我們沒有特別好的方法阻止一個類被其他類繼承,到了 C++11 有了 final 關鍵字我們就可以做到了。final 關鍵字修飾一個類,這個類將不允許被繼承,這在其他語言(如 Java)中早就實現了。在 C++ 11 中, final 關鍵字要寫在類名的后面,這在其他語言中是寫在 class 關鍵字前面的。示例如下:

classAfinal
{
};

classB:A
{
};

由于類 A 被聲明成 final, B 繼承 A, 所以編譯器會報如下錯誤提示類 A 不能被繼承:

errorC3246:'B':cannotinheritfrom'A'asithasbeendeclaredas'final'

3.2 override 關鍵字

C++98/03 語法規定,在父類中加了 virtual 關鍵字的方法可以被子類重寫,子類重寫該方法時可以加或不加 virtual 關鍵字,例如下面這樣:

classA
{
protected:
virtualvoidfunc(inta,intb)
{
}
};

classB:A
{
protected:
virtualvoidfunc(inta,intb)
{
}
};

classC:B
{
protected:
voidfunc(inta,intb)
{
}
};

這種寬松的規定可能會帶來以下兩個問題。

  • 當我們閱讀代碼時,無論子類重寫的方法是否添加了 virtual 關鍵字,我們都無法 直觀地確定該方法是否是重寫的父類方法。

  • 如果我們在子類中不小心寫錯了需要重寫的方法的函數簽名(可能是參數類型、 個數或返回值類型),這個方法就會變成一個獨立的方法,這可能會違背我們重寫 父類某個方法的初衷,而編譯器在編譯時并不會檢查到這個錯誤。

為了解決以上兩個問題, C++11 引進了 override 關鍵字,其實 override 關鍵字并不是新語法,在 Java 等其他編程語言中早就支持。類方法被 override 關鍵字修飾,表明該方法重寫了父類的同名方法,加了該關鍵字后,編譯器會在編譯階段做相應的檢查,如果其父類不存在相同簽名格式的類方法,編譯器就會給出相應的錯誤提示。情形一,父類不存在,子類標記了 override 的方法:

classA
{
};

classB:A
{
protected:
voidfunc(intk,intd)override
{
}
};

由于在父類 A 中沒有 func 方法,所以編譯器會提示錯誤:

errorC3668:'B::func':methodwithoverridespecifier'override'didnotoverride
anybaseclassmethods

情形二,父類存在,子類標記了 override 的方法,但函數簽名不一致:

classA
{
protected:
virtualintfunc(intk,intd)
{
return0;
}
};

classB:A
{
protected:
virtualvoidfunc(intk,intd)override
{
}
};

上述代碼編譯器會報同樣的錯誤。正確的代碼如下:

classA
{
protected:
virtualvoidfunc(intk,intd)
{
}
};

classB:A
{
protected:
virtualvoidfunc(intk,intd)override
{
}
};

3.3 default 語法

如果一個 C++類沒有顯式給出構造函數、析構函數、拷貝構造函數、 operator= 這幾類函數的實現,則在需要它們時,編譯器會自動生成;或者,在給出這些函數的聲明時,如果沒有給出其實現,則編譯器在鏈接時會報錯。如果使用=default 標記這類函數,則編譯器會給出默認的實現。來看一個例子:

classA
{
};

intmain()
{
Aa;
return0;
}

這樣的代碼是可以編譯通過的,因為編譯器默認生成 A 的一個無參構造函數,假設我們現在向 A 提供一個有參構造函數:

classA
{
public:
A(inti)
{
}
};

intmain()
{
Aa;
return0;
}

這時,編譯器就不會自動生成默認的無參構造函數了,這段代碼會編譯出錯,提示 A 沒有合適的無參構造函數:

errorC2512:'A':noappropriatedefaultconstructoravailable

我們這時可以手動為 A 加上無參構造函數, 也可以使用=default 語法強行讓編譯器自己生成:

classA
{
public:
A()=default;
A(inti)
{
}
};

intmain()
{
Aa;
return0;
}

=default 最大的作用可能是在開發中簡化了構造函數中沒有實際初始化代碼的寫法,尤其是聲明和實現分別屬于.h 和.cpp 文件。例如,對于類 A,其頭文件為 a.h,其實現文件為 a.cpp,則正常情況下我們需要在 a.cpp 文件中寫其構造函數和析構函數的實現(可能沒有實際的構造和析構邏輯):

//a.h
classA
{
public:
A();
~A();
};

//a.cpp
#include"a.h"

A::A()
{
}

A::~A()
{
}

可以發現,即使在 A 的構造函數和析構函數中什么邏輯也沒有,我們還是不得不在 a.cpp 中寫上構造函數和析構函數的實現。有了=default 關鍵字,我們就可以在 a.h 中直接寫成:

//a.h
classA
{
public:
A()=default;
~A()=default;
};

//a.cpp
#include"a.h"
//在cpp文件中就不用再寫A的構造函數和析構函數的實現了

3.4 =delete 語法

既然有強制讓編譯器生成構造函數、析構函數、拷貝構造函數、 operator=的語法,那么也應該有禁止編譯器生成這些函數的語法,沒錯,就是 =delete。在 C++ 98/03 規范中, 如果我們想讓一個類不能被拷貝(即不能調用其拷貝構造函數),則可以將其拷貝構造函數和 operator=函數定義成 private 的:

classA
{
public:
A()=default;
~A()=default;

private:
A(constA&a)
{
}

A&operator=(constA&a)
{
}
};

intmain()
{
Aa1;
Aa2(a1);
Aa3;
a3=a1;
return0;
}

通過以上代碼利用 a1 構造 a2 時,編譯器會提示錯誤:

errorC2248:'A::A':cannotaccessprivatememberdeclaredinclass'A'
errorC2248:'A::operator=':cannotaccessprivatememberdeclaredinclass'A'

我們利用這種方式間接實現了一個類不能被拷貝的功能,這也是繼承自 boost::noncopyable 的類不能被拷貝的實現原理?,F在有了=delete語法,我們直接使用該語法禁止編譯器生成這兩個函數即可:

classA
{
public:
A()=default;
~A()=default;
public:
A(constA&a)=delete;
A&operator=(constA&a)=delete;
};

intmain()
{
Aa1;
//Aa2(a1);
Aa3;
//a3=a1;
return0;
}

一般在一些工具類中, 我們不需要用到構造函數、 析構函數、 拷貝構造函數、 operator= 這 4 個函數,為了防止編譯器自己生成,同時為了減小生成的可執行文件的體積,建議使用=delete 語法禁止編譯器為這 4 個函數生成默認的實現代碼,例如:

//這是一個字符轉碼工具類
classEncodeUtil
{
public:
staticstd::wstringAnsiiToUnicode(conststd::string&strAnsii);
staticstd::stringUnicodeToAnsii(conststd::wstring&strUnicode);
staticstd::stringAnsiiToUtf8(conststd::string&strAnsii);
staticstd::stringUtf8ToAnsii(conststd::string&strUtf8);
staticstd::stringUnicodeToUtf8(conststd::wstring&strUnicode);
staticstd::wstringUtf8ToUnicode(conststd::string&strUtf8);

private:
EncodeUtil()=delete;
~EncodeUtil()=delete;
EncodeUtil(constEncodeUtil&rhs)=delete;
EncodeUtil&operator=(constEncodeUtil&rhs)=delete;
};

案例 4:對多線程的支持

我們來看一個稍微復雜一點的例子。在 C++11 之前,由于 C++98/03 本身缺乏對線程和線程同步原語的支持,我們要寫一個生產者消費者邏輯要這么寫。在 Windows 上:

/**
*RecvMsgTask.h
*/
classCRecvMsgTask:publicCThreadPoolTask
{
public:
CRecvMsgTask(void);
~CRecvMsgTask(void);

public:
virtualintRun();
virtualintStop();
virtualvoidTaskFinish();

BOOLAddMsgData(CBuffer*lpMsgData);

private:
BOOLHandleMsg(CBuffer*lpMsg);

private:
HANDLEm_hEvent;
CRITICAL_SECTIONm_csItem;
HANDLEm_hSemaphore;
std::vectorm_arrItem;
};

/**
*RecvMsgTask.cpp
*/
CRecvMsgTask::CRecvMsgTask(void)
{
::InitializeCriticalSection(&m_csItem);
m_hSemaphore=::CreateSemaphore(NULL,0,0x7FFFFFFF,NULL);
m_hEvent=::CreateEvent(NULL,TRUE,FALSE,NULL);
}

CRecvMsgTask::~CRecvMsgTask(void)
{
::DeleteCriticalSection(&m_csItem);

if(m_hSemaphore!=NULL)
{
::CloseHandle(m_hSemaphore);
m_hSemaphore=NULL;
}

if(m_hEvent!=NULL)
{
::CloseHandle(m_hEvent);
m_hEvent=NULL;
}
}

intCRecvMsgTask::Run()
{
HANDLEhWaitEvent[2];
DWORDdwIndex;
CBuffer*lpMsg;

hWaitEvent[0]=m_hEvent;
hWaitEvent[1]=m_hSemaphore;

while(1)
{
dwIndex=::WaitForMultipleObjects(2,hWaitEvent,FALSE,INFINITE);

if(dwIndex==WAIT_OBJECT_0)
break;

lpMsg=NULL;

::EnterCriticalSection(&m_csItem);
if(m_arrItem.size()>0)
{
//消費者從隊列m_arrItem中取出任務執行
lpMsg=m_arrItem[0];
m_arrItem.erase(m_arrItem.begin()+0);
}
::LeaveCriticalSection(&m_csItem);

if(NULL==lpMsg)
continue;

//處理任務
HandleMsg(lpMsg);

deletelpMsg;
}

return0;
}

intCRecvMsgTask::Stop()
{
m_HttpClient.SetCancalEvent();
::SetEvent(m_hEvent);
return0;
}

voidCRecvMsgTask::TaskFinish()
{
}

//生產者調用這個方法將Task放入隊列m_arrItem中
BOOLCRecvMsgTask::AddMsgData(CBuffer*lpMsgData)
{
if(NULL==lpMsgData)
returnFALSE;

::EnterCriticalSection(&m_csItem);
m_arrItem.push_back(lpMsgData);
::LeaveCriticalSection(&m_csItem);

::ReleaseSemaphore(m_hSemaphore,1,NULL);

returnTRUE;
}

Linux 下:

#include
#include
#include
#include
#include
#include

classTask
{
public:
Task(inttaskID)
{
this->taskID=taskID;
}

voiddoTask()
{
std::cout<"handleatask,taskID:"<",threadID:"<tasks;
pthread_cond_tmycv;

void*consumer_thread(void*param)
{
Task*pTask=NULL;
while(true)
{
pthread_mutex_lock(&mymutex);
while(tasks.empty())
{
//如果獲得了互斥鎖,但是條件不合適的話,pthread_cond_wait會釋放鎖,不往下執行。
//當發生變化后,條件合適,pthread_cond_wait將直接獲得鎖。
pthread_cond_wait(&mycv,&mymutex);
}

pTask=tasks.front();
tasks.pop_front();

pthread_mutex_unlock(&mymutex);

if(pTask==NULL)
continue;

pTask->doTask();
deletepTask;
pTask=NULL;
}

returnNULL;
}

void*producer_thread(void*param)
{
inttaskID=0;
Task*pTask=NULL;

while(true)
{
pTask=newTask(taskID);

pthread_mutex_lock(&mymutex);
tasks.push_back(pTask);
std::cout<"produceatask,taskID:"<",threadID:"<returnNULL;
}

intmain()
{
pthread_mutex_init(&mymutex,NULL);
pthread_cond_init(&mycv,NULL);

//創建5個消費者線程
pthread_tconsumerThreadID[5];
for(inti=0;ifor(inti=0;ireturn0;
}

怎么樣?上述代碼如果對于新手來說,望而卻步。為了實現這樣的功能在 Windows 上你需要掌握線程如何創建、線程同步對象 CriticalSection、Event、Semaphore、WaitForSingleObject/WaitForMultipleObjects 等操作系統對象和 API。

在 Linux 上需要掌握線程創建,你需要了解線程創建、互斥體、條件變量。對于需要支持多個平臺的開發,需要開發者同時熟悉上述原理并編寫多套適用不同平臺的代碼。C++11 的線程庫改變了這個現狀,現在你只需要掌握 std::thread、std::mutex、std::condition_variable 少數幾個線程同步對象即可,同時使用這些對象編寫出來的代碼也可以跨平臺。示例如下:

#include
#include
#include
#include
#include

classTask
{
public:
Task(inttaskID)
{
this->taskID=taskID;
}

voiddoTask()
{
std::cout<"handleatask,taskID:"<",threadID:"<tasks;
std::condition_variablemycv;

void*consumer_thread()
{
Task*pTask=NULL;
while(true)
{
std::unique_lockguard(mymutex);
while(tasks.empty())
{
//如果獲得了互斥鎖,但是條件不合適的話,pthread_cond_wait會釋放鎖,不往下執行。
//當發生變化后,條件合適,pthread_cond_wait將直接獲得鎖。
mycv.wait(guard);
}

pTask=tasks.front();
tasks.pop_front();

if(pTask==NULL)
continue;

pTask->doTask();
deletepTask;
pTask=NULL;
}

returnNULL;
}

void*producer_thread()
{
inttaskID=0;
Task*pTask=NULL;

while(true)
{
pTask=newTask(taskID);

//使用括號減小guard鎖的作用范圍
{
std::lock_guardguard(mymutex);
tasks.push_back(pTask);
std::cout<"produceatask,taskID:"<",threadID:"<returnNULL;
}

intmain()
{
//創建5個消費者線程
std::threadconsumer1(consumer_thread);
std::threadconsumer2(consumer_thread);
std::threadconsumer3(consumer_thread);
std::threadconsumer4(consumer_thread);
std::threadconsumer5(consumer_thread);

//創建一個生產者線程
std::threadproducer(producer_thread);

producer.join();
consumer1.join();
consumer2.join();
consumer3.join();
consumer4.join();
consumer5.join();

return0;
}

感覺如何?代碼既簡潔又統一。這就是 C++11 之后使用 Modern C++ 開發的效率!C++11 之后的 C++ 更像一門新的語言。當 C++11 的編譯器發布之后(Visual Studio 2013、g++4.8),我第一時間更新了我的編譯器,同時把我們的項目使用了 C++11 特性進行了改造。當然,例子還有很多,限于文章篇幅,這里就列舉 4 個案例。

當然,Modern C++ 已經成為業界開發的主流,你應該歡迎它、擁抱它、熟悉它、使用它。

編輯:jq
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Linux
    +關注

    關注

    87

    文章

    11322

    瀏覽量

    209861
  • API
    API
    +關注

    關注

    2

    文章

    1505

    瀏覽量

    62174
  • C++
    C++
    +關注

    關注

    22

    文章

    2112

    瀏覽量

    73717
  • 代碼
    +關注

    關注

    30

    文章

    4803

    瀏覽量

    68752

原文標題:Modern C++ 有哪些能真正提升開發效率的語法糖?

文章出處:【微信號:LinuxHub,微信公眾號:Linux愛好者】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    AKI跨語言調用庫神助攻C/C++代碼遷移至HarmonyOS NEXT

    產品創新與功能迭代,而非技術遷移的細節問題,大幅提升開發效率。 據悉,在涉及C/C++/ETS跨越語言調用的鴻蒙化應用中,
    發表于 01-02 17:08

    C語言和C++中結構體的區別

    同樣是結構體,看看在C語言和C++中有什么區別?
    的頭像 發表于 10-30 15:11 ?286次閱讀

    C7000優化C/C++編譯器

    電子發燒友網站提供《C7000優化C/C++編譯器.pdf》資料免費下載
    發表于 10-30 09:45 ?0次下載
    <b class='flag-5'>C</b>7000優化<b class='flag-5'>C</b>/<b class='flag-5'>C++</b>編譯器

    OpenVINO2024 C++推理使用技巧

    很多人都使用OpenVINO新版的C++ 或者Python的SDK,都覺得非常好用,OpenVINO2022之后的版本C++ SDK做了大量的優化與整理,已經是非常貼近開發的使用習慣與推理方式。與OpenCV的Mat對象對接方式
    的頭像 發表于 07-26 09:20 ?994次閱讀

    C++語言基礎知識

    電子發燒友網站提供《C++語言基礎知識.pdf》資料免費下載
    發表于 07-19 10:58 ?7次下載

    C++中實現類似instanceof的方法

    C++多態與繼承,但是很多人開始學習C++,有時候會面臨一個常見問題,就是如何向下轉型,特別是不知道具體類型的時候,這個時候就希望C++ 可以向Java或者Python中有insta
    的頭像 發表于 07-18 10:16 ?613次閱讀
    <b class='flag-5'>C++</b>中實現類似instanceof的方法

    鴻蒙OS開發實例:【Native C++

    使用DevEco Studio創建一個Native C++應用。應用采用Native C++模板,實現使用NAPI調用C標準庫的功能。使用C標準庫hypot接口計算兩個給定數平方和的平
    的頭像 發表于 04-14 11:43 ?2681次閱讀
    鴻蒙OS<b class='flag-5'>開發</b>實例:【Native <b class='flag-5'>C++</b>】

    使用 MISRA C++:2023? 避免基于范圍的 for 循環中的錯誤

    在前兩篇博客中,我們?向您介紹了新的 MISRA C++ 標準?和?C++ 的歷史?。在這篇博客中,我們將仔細研究以 C++ 中?for?循環為中心的特定規則。
    的頭像 發表于 03-28 13:53 ?822次閱讀
    使用 MISRA <b class='flag-5'>C++</b>:2023? 避免基于范圍的 for 循環中的錯誤

    為什么很少用C++開發單片機

    C語言是面向過程的語言,C++是面向對象的編程語言。結合本文來說,面向過程相比面向對象的編程,生成代碼量(bin文件)更小,運行效率更高。
    發表于 03-25 14:26 ?1050次閱讀
    為什么很少用<b class='flag-5'>C++</b><b class='flag-5'>開發</b>單片機

    請問CubeIDE如何支持C++開發?

    CubeIDE如何支持C++開發。有沒有一些例程。
    發表于 03-25 06:22

    潞晨科技Colossal-AI + 浪潮信息AIStation,大模型開發效率提升10倍

    的潞晨科技Colossal-AI系統,用戶可實現在本地算力平臺一鍵訓練、微調、推理、部署大模型,將大模型開發效率提升10倍以上,并將算力效率提升
    的頭像 發表于 03-01 09:43 ?502次閱讀
    潞晨科技Colossal-AI + 浪潮信息AIStation,大模型<b class='flag-5'>開發</b><b class='flag-5'>效率</b><b class='flag-5'>提升</b>10倍

    c語言,c++,java,python區別

    C語言、C++、Java和Python是四種常見的編程語言,各有優點和特點。 C語言: C語言是一種面向過程的編程語言。它具有底層的特性,能夠對計算機硬件進行直接操作。
    的頭像 發表于 02-05 14:11 ?2460次閱讀

    vb語言和c++語言的區別

    Microsoft開發的一種面向對象的事件驅動編程語言。它的設計目標是簡化編程過程,讓初學者也快速上手。與之相比,C++語言是一種通用的、面向對象的編程語言,其設計目標是提供高性能的系統級編程。
    的頭像 發表于 02-01 10:20 ?2387次閱讀

    C++在Linux內核開發中從爭議到成熟

    Linux 內核郵件列表中一篇已有六年歷史的老帖近日再次引發激烈討論 —— 主題是建議將 Linux 內核的開發語言從 C 轉換為更現代的 C++。
    的頭像 發表于 01-31 14:11 ?650次閱讀
    <b class='flag-5'>C++</b>在Linux內核<b class='flag-5'>開發</b>中從爭議到成熟

    C++簡史:C++是如何開始的

    MISRA C++:2023,MISRA? C++ 標準的下一個版本,來了!為了幫助您做好準備,我們介紹了 Perforce 首席技術支持工程師 Frank van den Beuken 博士撰寫
    的頭像 發表于 01-11 09:00 ?622次閱讀
    <b class='flag-5'>C++</b>簡史:<b class='flag-5'>C++</b>是如何開始的
    主站蜘蛛池模板: 久久有码中文字幕| 日本高清不卡一区久久精品| 国产午夜a理论毛片在线影院| 国产1000部成人免费视频 | 牛牛免费视频| 桥本有菜黑丝| 忘忧草在线社区WWW日本-韩国| 亚洲成人黄色在线| 怡春院院日本一区二区久久| 69久久国产精品热88人妻| 啊好大好厉害好爽真骚| 国产精品久久国产三级国不卡顿| 国产在线精品一区二区在线看 | 中文字幕成人| AV久久久囯产果冻传媒| 国产成+人+综合+亚洲不卡| 好男人WWW免费高清视频在线 | 97久久精品人人槡人妻人| 苍井空教师BD在线观看全集| 国产成人免费视频| 黄色毛片a| 农民工老头在出租屋嫖老熟女| 日日噜噜夜夜躁躁狠狠| 亚洲国产无线码在线观看| 91羞羞视频| 国产精品大全国产精品| 久久vs国产综合色| 欧美性最猛xxxx在线观看视频| 我年轻漂亮的继坶2中字在线播放| 亚洲视频在线观看免费| a级毛片黄免费a级毛片| 国产精品毛片在线视频| 久久机热视频 这里只有精品首页| 强上轮流内射高NP男男| 亚洲精品乱码久久久久久直播 | 三级黄在线| 樱花草在线观看影院| 成人无码精品一区二区在线观看 | 亚洲中文字幕AV在天堂| av天堂电影网| 果冻传媒在线播放|