真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

C++霧中風(fēng)景18:C++20, 從concept開(kāi)始

轉(zhuǎn)眼間,C++20的標(biāo)準(zhǔn)已經(jīng)發(fā)布快兩年了。不少C++的開(kāi)源項(xiàng)目也已經(jīng)將標(biāo)準(zhǔn)升級(jí)到最新的C++20了,筆者也開(kāi)啟了新標(biāo)準(zhǔn)的學(xué)習(xí)歷程了。所以借這系列的博文,記錄下筆者學(xué)習(xí)新標(biāo)準(zhǔn)的一些心得與吐槽~~
作為C++20系列的第一篇開(kāi)篇之文,就要從千呼萬(wàn)喚始處理的concept聊起了,后續(xù)很多新的feature的實(shí)現(xiàn),也仰賴新的concept的實(shí)現(xiàn),后續(xù)筆者的文章也會(huì)逐步展開(kāi)。OK,開(kāi)始我們C++20旅程的第一站:concept

創(chuàng)新互聯(lián)從2013年開(kāi)始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站制作、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元霍州做網(wǎng)站,已為上家服務(wù),為霍州各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108

1.First Look

先從一個(gè)群友的一個(gè)實(shí)際的問(wèn)題出發(fā),我們來(lái)看看concept可以解決什么問(wèn)題。是怎么樣通過(guò)coding實(shí)現(xiàn)的。

  • SFINAE
    熟悉C++模板編程的小伙伴肯定第一時(shí)間想到通過(guò)SFINAE的方式來(lái)解決,讓筆者來(lái)解決這個(gè)問(wèn)題的話,會(huì)寫(xiě)出下面的代碼:
template 
T test(T a) {
    static_assert(!std::is_same_v);
    static_assert(!std::is_same_v);
    static_assert(!std::is_same_v);
    static_assert(!std::is_same_v);
    return a;
}

這里寫(xiě)的代碼是一個(gè)略微Trick的表達(dá),利用decltype去獲取操作符計(jì)算后的類型,然后用std::is_same_v進(jìn)行一個(gè)其實(shí)沒(méi)什么意義的類型比較,來(lái)滿足static_assert的語(yǔ)義,最終滿足我們對(duì)模板類型T的一些約束。

  • concept
    顯然上面的方式是很不直觀的,雖然能達(dá)到咱們的目的,但是從代碼優(yōu)雅角度來(lái)說(shuō)是一種較差的選擇實(shí)現(xiàn)。

我們來(lái)看一下用C++20提供給我們的Concept是如何解決這個(gè)問(wèn)題的:

template 
concept Cal = requires (T a) {
    a + a;
    a - a;
    a * a;
    a / a;
};

template 
requires Cal
T test(T a) {
    return a;
}

這是通過(guò)concept來(lái)實(shí)現(xiàn)的一個(gè)類型約束方式,Cal代表著一個(gè)concept的實(shí)現(xiàn),requires中花括號(hào)的內(nèi)容就代表了對(duì)于類型T的約束,要滿足下面的操作符

a + a;
a - a;
a * a;
a / a;

Bingo! 似乎C++20給了我們一個(gè)更好的trait,接著往下看,我們繼續(xù)來(lái)細(xì)探Concept的實(shí)現(xiàn)。

2. How to use

  • concept的定義

這里寫(xiě)了一個(gè)例子,咱們基于這個(gè)例子來(lái)展開(kāi):

template 
concept Cal = requires (T a) {
    a + a;
    typename T::type;
   {a + a} -> std::same_as;
    require  Concept2;
};

這里定義了4個(gè)requires的要求,只有滿足這4個(gè)條件才能通過(guò)concept的限制,正常進(jìn)行編譯。

1). a + a這個(gè)是最簡(jiǎn)單的,該表達(dá)式能通過(guò)編譯則代表符合要求,這里不會(huì)進(jìn)行實(shí)際的計(jì)算。
2). typename T::type代表需要,T類型定義了type類型,才符合要求
3). {a + a} -> std::same_as 這里的{}代表了decltype(a + a)之后的類型需要滿足后面的concept的需求。這是一個(gè)語(yǔ)法糖,也可以通過(guò)這樣來(lái)實(shí)現(xiàn):requires std::is_floating_point_v
4). 最后的require Concept2這代表了concept的嵌套邏輯。requires后面可以帶任意的concept

  • concept的使用

了解了concept定義之后,我們就可以利用concept來(lái)進(jìn)行模板類型的約束了。
這里“回字有四種寫(xiě)法”,大家可以選擇自己喜歡的方式來(lái)使用。(真搞不懂搞這么多寫(xiě)法干什么,不能統(tǒng)一一下嗎?, 下面介紹的順序隨筆者的偏好以此遞減)

template 
requires Cal
T test(T a)
{
    return a + a;
}

1). 這是筆者最認(rèn)可的一種書(shū)寫(xiě)方式,語(yǔ)義明確,在模板類型定義之后明確對(duì)它的要求。

template 
T test(T a)
{
    return a + a;
}

2). 也還行吧,模板參數(shù)前指定了concept,也比較明確直觀。

Cal test(Cal a)
{
    return a + a;
}

3). concept命名一長(zhǎng)就顯得有些瑣碎了,并且把concept當(dāng)類型使用了,看起來(lái)有些怪異了。

template 
T test(T a) requires Cal
{
    return a + a;
}

4). 把concept寫(xiě)后面的都是異端,當(dāng)然如果你喜歡的話,也ok。

3. concept的本質(zhì)

concept本質(zhì)上是:一個(gè)可以套用在模板上的constexpr bool值。

相信下面這段代碼能幫助你更好的理解它:

template 
concept Con = std::is_floating_point_v;

int main(int argc, char* argv[]) {
    static_assert(std::is_same_v), bool>);
    std::cout << Con << std::endl;
    return 0;
}

顯然,上面的代碼我們用is_same_v確定了concept生成的類型就是bool類型。而同樣的,在運(yùn)行期,咱們也可以將concept的結(jié)果作為一個(gè)bool常量進(jìn)行使用,并打印。

所以,take it easy。 concept很簡(jiǎn)單,它只是C++20給你提供的一個(gè)better的工具,來(lái)擺脫被瘋狂的模板報(bào)錯(cuò)所支配的恐懼。但即使你完全不了解它,使用老的方式,依然能夠同樣解決問(wèn)題。

4.小結(jié)

C++的一些模板推斷的錯(cuò)誤常常讓人抓狂。而很多時(shí)候我們使用它需要

  • 要進(jìn)行模板推斷類型的編程設(shè)計(jì)
  • 利用SFINAE的方式來(lái)類型約束

這無(wú)形之中增加Coding時(shí)的心智成本,而concept作為一個(gè)新的語(yǔ)法糖,給了我們拆分二者的機(jī)會(huì):讓上帝歸上帝,凱撒歸凱撒。
使用好concept來(lái)進(jìn)行類型約束,enjoy新標(biāo)準(zhǔn)帶來(lái)的便利吧。

希望大家能夠有所收獲,筆者水平有限。成文之處難免有理解謬誤之處,歡迎大家多多討論,指教。

5.參考資料

CppReference


分享名稱:C++霧中風(fēng)景18:C++20, 從concept開(kāi)始
轉(zhuǎn)載源于:http://weahome.cn/article/dsogoop.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部