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

C++中constexpr與函數(shù)參數(shù)轉(zhuǎn)發(fā)的操作方法

 更新時間:2024年02月27日 10:23:01   作者:leapmotion  
constexpr是c++11引入的關(guān)鍵字,c++11的constexpr的函數(shù)中只是支持單句代碼,c++14限制放寬,可以在里邊寫循環(huán)及邏輯判斷等語句,本文探討關(guān)于constexpr的函數(shù)中參數(shù)的現(xiàn)象,以及如果參數(shù)是constexpr如何做轉(zhuǎn)發(fā),感興趣的朋友一起看看吧

本文和大家探討下關(guān)于constexpr的函數(shù)中參數(shù)的現(xiàn)象,以及如果參數(shù)是constexpr如何做轉(zhuǎn)發(fā)

關(guān)于constexpr函數(shù)

constexpr是c++11引入的關(guān)鍵字,c++11的constexpr的函數(shù)中只是支持單句代碼,c++14限制放寬,可以在里邊寫循環(huán)及邏輯判斷等語句。
constexpr形容函數(shù)表示該函數(shù)被編譯期計算或者調(diào)用。但是只能是可能被編譯期計算,舉例來說:

constexpr int square(int num) {
    return num * num;
}

假設(shè)這里有一個計算平方的函數(shù)是constexpr形容,那么我如果這樣調(diào)用:

int main() {
    int val = square(12);
}

我們可以看下編譯后的匯編:

main:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], 144 // 這里
        mov     eax, 0
        pop     rbp
        ret

可以看到main函數(shù)里在運行時根本沒有去調(diào)用square函數(shù),而是在編譯期直接將square函數(shù)計算得出144并賦值。也就是說傳遞參數(shù)是字面量(或者constexpr變量)可以被認(rèn)定是編譯期調(diào)用。

那么我們?nèi)绻麚Q一種方式調(diào)用呢?

int main() {
    int p = 12;
    int val = square(p);
}

通過參數(shù)傳遞進(jìn)來,再來看下匯編:

square(int):
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     eax, DWORD PTR [rbp-4]
        imul    eax, eax
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 12
        mov     eax, DWORD PTR [rbp-4]
        mov     edi, eax
        call    square(int)
        mov     DWORD PTR [rbp-8], eax
        mov     eax, 0
        leave
        ret

略顯復(fù)雜,不需要關(guān)注很多匯編代碼,我們只需要知道運行時確實會去執(zhí)行square函數(shù)。

constexpr函數(shù)小結(jié)

那也就是說constexpr函數(shù)并不是完全是編譯期執(zhí)行,編譯器其實和你傳遞的參數(shù)或者函數(shù)內(nèi)部的一些邏輯來判斷。

constexpr參數(shù)傳遞

這里假設(shè)有一個這樣的例子:

// ...
struct AddSum {
    void add(int val) {
        constexpr auto sq = square(val);
        sum += sq;
    }
    int sum = 0;
};
int main() {
    constexpr int p = 12;
    AddSum a;
    a.add(p);
    return 0;    
}

需要把一些編譯期的數(shù)字的平方加起來,在add函數(shù)中使用constexpr來接收square的返回值,因為這樣可以使得square是編譯期執(zhí)行的,不過可惜的是這里不能通過編譯,因為square不能確定val是不是constexpr。但是我們明明傳遞的就是constexpr的變量。那么問題來了,如何在傳參數(shù)的時候能夠?qū)?code>constexpr的屬性進(jìn)行傳遞呢?

C++并不支持在形參使用constexpr限制:

// error: Function parameter cannot be constexpr
void add(constexpr int val) { 
    // ...
}

且使用完美轉(zhuǎn)發(fā)也不能將constexpr進(jìn)行傳遞。

template<typename T>
void add(T&& val) {
     constexpr auto sq = square(val); // error
}

使用非類型模板參數(shù)

既然用到了模板,那么我們完全可以將val作為非類型的模板參數(shù)進(jìn)行傳遞:

template<int val>
void add() {
    constexpr auto sq = square(val);
    sum += sq;
}

如果這里就結(jié)束的話,那確實不值得討論了,非類型模板參數(shù)的問題是只能傳遞一些基本類型,我們自定的類constexpr對象則不能傳遞。

值內(nèi)嵌的類型

其實我們可以借助一個helper類,將要傳遞的值封裝在這里類里,然后需要的時候取出來。如下:

struct Helper {
    static constexpr int value() {
        return 12;
    }
};
struct AddSum {
    template<typename H>
    void add(H) {
        constexpr auto sq = square(H::value());
        sum += sq;
    }
    int sum = 0;
};
int main() {
    AddSum a;
    a.add(Helper{});
    return 0;
}

可以看到我們Helper中value用來封裝了要傳遞的int值,然后將Helper的對象傳遞給add,進(jìn)一步可以獲取到value。

這里不能通用,因為我們需要在helper里寫死這個值,又沒辦法將值傳遞給helper,感覺又繞回來了。哈哈,這里我們使用宏來定義一個通用的模式:

#define CONSTEXPR_HELPER(...)                 \
struct Helper {                               \
    static constexpr decltype(auto) value() { \
        return __VA_ARGS__;                   \
    }                                         \
};
int main() {
    AddSum a;
    using H = CONSTEXPR_HELPER(12);
    a.add(H{});
    return 0;
}

這種情況下就可以使用任意類型的的constexpr屬性進(jìn)行傳遞了。同時也可以將值在調(diào)用時傳遞而不是寫死。

constexpr的lambda表達(dá)式

C++17出現(xiàn)了constexpr形式的lambda表達(dá)式,我們可以借助它來實現(xiàn)constexpr的傳遞

struct AddSum {
    template<typename H>
    void add(H h) {
        constexpr auto sq = square(h());
        sum += sq;
    }
    int sum = 0;
};
int main() {
    AddSum a;
    a.add([](){
        return 12;
    });
    return 0;
}

這里我們使用constexpr的lambda對象傳遞給add函數(shù),同時傳遞過來的lambda表達(dá)式仍然具有l(wèi)ambda屬性,然后調(diào)用將值獲取到。

這樣也就是在C++17版本不需要使用宏來定義內(nèi)嵌值的類型。

總結(jié)

本篇文章就是和大家探討下constexpr的參數(shù)傳遞的問題,可以使用非類型模板參數(shù),宏定義,lambda表達(dá)式做到。

感謝大家,點個贊吧~

ref

https://mpark.github.io/programming/2017/05/26/constexpr-function-parameters/

到此這篇關(guān)于C++中constexpr與函數(shù)參數(shù)轉(zhuǎn)發(fā)的文章就介紹到這了,更多相關(guān)constexpr函數(shù)參數(shù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

三门县| 锡林郭勒盟| 德清县| 赣州市| 扶绥县| 岳普湖县| 凉城县| 赣榆县| 金堂县| 阆中市| 沙雅县| 永清县| 新野县| 黔西县| 行唐县| 繁峙县| 波密县| 察隅县| 福鼎市| 延津县| 鄱阳县| 濮阳县| 肃宁县| 拜城县| 霞浦县| 民勤县| 梧州市| 林州市| 商都县| 台江县| 屏东县| 盈江县| 西丰县| 拉萨市| 海城市| 汉寿县| 那曲县| 屏东市| 克什克腾旗| 石屏县| 兴化市|