在前文對const的幾種形式進行了分析說明,但是constexpr if的應(yīng)用沒有顧及到。在模板元編程constexpr可以起到一種類似于if else的作用。畢竟不管在哪里運行,哪個時期運行,條件判斷總是需要的。在早期的模板編程中,如果想做這種判斷需要使用常見的如enable_if之類的模板,特別是c++的靈活性會產(chǎn)生一些代碼,它不符合c++的規(guī)范(即不推薦這么寫),但又被編譯使用(c++又支持),這種情況被稱做ill-formed
,如果是類型則ill-formed type,cppreference稱之為非良構(gòu)類型。
這就又回到前面提到的SFINAE和Concepts,而在模板板的元編程里這又一是種強需求,所以以這條線來看c++標準的迭代,就會看到,對類似的支持是越來越完善。明白了這些,再回頭學習和應(yīng)用constexpr if就會有的放矢,知其然,并知其所以然。
先看一個例子,來理解constexpr if:
//C++17以前
templatestd::enable_if_t::value, std::string>to_string(T t){
return std::to_string(t);
}
?
templatestd::enable_if_t::value, std::string>to_string(T t){
return t;
}
//c++17以后
templateauto to_string(T t) {
if constexpr(std::is_integral::value) {
return std::to_string(t);
} else {
return t;
}
}
一般來說,在模板中進行分支控制主要有以下幾種情況,一個是采用偏特化機制,對不同的類型參數(shù)輸入產(chǎn)生不同的結(jié)果,這個在前面的false_type中就有體現(xiàn);另外一個是使用std::enable_if_t來實現(xiàn);然后就是今天分析的constexpr if。在編譯器控制分支的情況下,在c++17以前,無論哪種分支,都是會被編譯的,但是在c++17后,不會控制到的則不會編譯,不過雖然如此,另外的分支仍然要符合c++的語法,否則仍然是無法編譯通過。
上面這個例子把偏特化的例子省略了,其實從模板元編程的角度看,就是對SFINAE技術(shù)的一個優(yōu)化和簡化的過程。把這些基本的情況了解后,回頭再看constexpr if就會有一個比較深刻的理解。
然后來分析一下它的定義:constexpr if是一種在編譯期進行分支控制的寫法,constexpr可以緊跟在if的后面。通過對條件塊中不滿足的部分直接處理掉,但是這有一個前提,這個條件塊必須是一個常量表達式并且可以顯示的轉(zhuǎn)換成布爾值。
前面提到過constexptr if主要是對模板元編程的支持,它能夠起到讓代碼更直觀,更簡便,使得在編譯期內(nèi)的元編程不再像SFINAE那樣晦澀。下面再看一個數(shù)列的計算:
#pragma once
templateconstexpr long Fib() {
if constexpr (N >= 2) {
return Fib() + Fib();
}
else {
return N;
}
}
void TestFib() {
static_assert(Fib<0>() == 0);
static_assert(Fib<1>() == 1);
static_assert(Fib<2>() == 1);
static_assert(Fib<3>() == 2);
}
int main()
{
TestFib();
return 0;
}
這個例子沒有判斷值的范圍,但是這里重點是講constexpr if的用法,所以不必太再乎這個。是不是非常簡單,它和印象中在執(zhí)行期運行的代碼已經(jīng)長得很像了。
使用constexpr if優(yōu)點不少,它可以減少代碼的編譯生成數(shù)量,也可以更簡潔是了,但它也不少的受限情況:比如函數(shù)和運行期類似,在某些情況下沒有寫constexpr仍然可以運行,而這種運行則無法在編譯期優(yōu)化了。同時,其多多類型返回無能為力。所以在實際應(yīng)用中,還是要小心為妙。
總體來看,constexpr if的應(yīng)用場景還是很受限的,它只能放在一般意義的函數(shù)內(nèi)部,如果必須需要減小編譯出的代碼文件的大小,盡量減少依賴資源,它還是有可能施展身手的。更具體的情況需要開發(fā)者根據(jù)需要來確定它的應(yīng)用。
constexpr的詳細用法不同版本都在網(wǎng)上有詳細的說明,但如何能更好的在何處使用它,這才是一個比較讓人頭疼的問題。正如上學一樣,老師一講就明白,自己做題就糊涂。如何打破這個怪圈,就需要從基礎(chǔ)入手,反復把基礎(chǔ)的知識吃透,然后再結(jié)合例程自己不斷修改完善,才有機會沖出桎梏,解放思想。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧