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

C++11/C++14中constexpr的使用案例詳解

 更新時(shí)間:2023年06月09日 16:24:33   作者:fengbingchun  
C++11規(guī)定,允許將變量聲明為constexpr類型以便由編譯器來驗(yàn)證變量的值是否是一個(gè)常量表達(dá)式,這篇文章主要介紹了C++11/C++14中constexpr的使用,需要的朋友可以參考下

      常量表達(dá)式(const expression)是指值不會(huì)改變并且在編譯過程中就能得到計(jì)算結(jié)果的表達(dá)式。字面值屬于常量表達(dá)式,用常量表達(dá)式初始化的const對象也是常量表達(dá)式。

      只要有可能使用constexpr,就使用它。

      C++11中constexpr的使用

      constexpr是C++11中添加的一個(gè)特性,其主要思想是通過在編譯時(shí)而不是運(yùn)行時(shí)進(jìn)行計(jì)算來提高程序的性能,將時(shí)間花在編譯上,而在運(yùn)行時(shí)節(jié)省時(shí)間(類似于模版元編程)。

      C++11規(guī)定,允許將變量聲明為constexpr類型以便由編譯器來驗(yàn)證變量的值是否是一個(gè)常量表達(dá)式。聲明為constexpr的變量一定是一個(gè)常量,而且必須用常量表達(dá)式初始化。

      盡管不能使用普通函數(shù)作為constexpr變量的初始值,但C++11標(biāo)準(zhǔn)允許定義一種特殊的constexpr函數(shù)。這種函數(shù)應(yīng)該足夠簡單以使得編譯時(shí)就可以計(jì)算其結(jié)果,這樣就能用constexpr函數(shù)去初始化constexpr變量了。

      一般來說,如果你認(rèn)定變量是一個(gè)常量表達(dá)式,那就把它聲明成constexpr類型。

      所有constexpr對象都是const對象,而并非所有的const對象都是constexpr對象。如果你想讓編譯器提供保證,讓變量擁有一個(gè)值,用于要求編譯期常量的語境,那么能達(dá)到這個(gè)目的的工具是constexpr,而非const。

      constexpr函數(shù)是指能用于常量表達(dá)式的函數(shù)。定義constexpr函數(shù)的方法與其它函數(shù)類似,不過要遵循幾項(xiàng)約定:函數(shù)的返回類型及所有形參的類型都得是字面值類型,而且函數(shù)體中必須有且只有一條return語句。constexpr函數(shù)或構(gòu)造函數(shù)被隱式地指定為內(nèi)聯(lián)函數(shù)。

      constexpr函數(shù)體內(nèi)也可以包含其它語句,只要這些語句在運(yùn)行時(shí)不執(zhí)行任何操作就行。例如,constexpr函數(shù)中可以有空語句、類型別名以及using聲明

      允許constexpr函數(shù)的返回值并非一個(gè)常量。constexpr函數(shù)不一定返回常量表達(dá)式。

      和其它函數(shù)不一樣,內(nèi)聯(lián)函數(shù)和constexpr函數(shù)可以在程序中多次定義。不過,對于某個(gè)給定的內(nèi)聯(lián)函數(shù)或者constexpr函數(shù)來說,它的多個(gè)定義必須完全一致?;谶@個(gè)原因,內(nèi)聯(lián)函數(shù)和constexpr函數(shù)通常定義在頭文件中。

      constexpr函數(shù)只能調(diào)用其它c(diǎn)onstexpr函數(shù),不能調(diào)用簡單函數(shù)(simple function)。constexpr函數(shù)不應(yīng)該是void類型。constexpr函數(shù)中不允許有前綴增量(++i),在C++14中已刪除此限制。

      constexpr函數(shù)的理解

      (1).constexpr函數(shù)可以用在要求編譯期常量的語境中。在這樣的語境中,若你傳給一個(gè)constexpr函數(shù)的實(shí)參值是在編譯期已知的,則結(jié)果也會(huì)在編譯期間計(jì)算出來。如果任何一個(gè)實(shí)參值在編譯期未知,則你的代碼將無法通過編譯。

      (2).在調(diào)用constexpr函數(shù)時(shí),若傳入的值有一個(gè)或多個(gè)在編譯期未知,則它的運(yùn)作方式和普通函數(shù)無異,亦即它也是在運(yùn)行期執(zhí)行結(jié)果的計(jì)算。這意味著,如果函數(shù)執(zhí)行的是同樣的操作,僅僅應(yīng)用的語境一個(gè)是要求編譯期常量的,一個(gè)是用于所有其它值的話,那就不必寫兩個(gè)函數(shù)。constexpr函數(shù)就可以同時(shí)滿足所有需求。

      constexpr函數(shù)僅限于傳入和返回字面類型(literal type),意思就是這樣的類型能夠持有編譯期可以決議的值。在C++11中,所有的內(nèi)建類型,除了void,都符合這個(gè)條件。但是用戶自定義類型同樣可能也是字面類型,因?yàn)樗臉?gòu)造函數(shù)和其它成員函數(shù)可能也是constexpr函數(shù)。

      在C++11中,constexpr函數(shù)都隱式地被聲明為const。

      以下為測試代碼:

namespace {
// constexpr function: constexpr函數(shù)被隱式地指定為內(nèi)聯(lián)函數(shù)
constexpr int new_sz() { return 42; }
constexpr size_t scale(size_t cnt) { return new_sz() * cnt; }
constexpr int product(int x, int y) { return (x * y); }
// pow前面寫的那個(gè)constexpr并不表明pow要返回一個(gè)const值,它表明的是如果base和exp是編譯期常量,pow的返回結(jié)果
// 就可以當(dāng)一個(gè)編譯期常量使用;如果base和exp中有一個(gè)不是編譯期常量,則pow的返回結(jié)果就將在執(zhí)行期計(jì)算
constexpr int pow(int base, int exp) noexcept
{
	return (exp == 0 ? 1 : base * pow(base, exp - 1));
}
} // namespace
int test_constexpr_1()
{
	// constexpr variables
	constexpr int mf = 20; // 20 is a constant expression
	constexpr int limit = mf + 1; // mf + 1 is a constant expression
	constexpr int foo = new_sz(); // foo is a constant expression
	std::cout << "foo:" << foo << "\n"; // foo:42
	// 當(dāng)scale的實(shí)參是常量表達(dá)式時(shí),它的返回值也是常量表達(dá)式;反之則不然
	int arr[scale(2)]; // ok
	int i = 2;
	//int a2[scale(i)]; // error: scale(i)不是常量表達(dá)式
	size_t value = scale(i); // ok,constexpr函數(shù)不一定返回常量表達(dá)式
	std::cout << "value:" << value << "\n"; // value:84
	int sz = 1;
	//constexpr auto array_size = sz; // error, sz的值在編譯期未知
	const auto array_size1 = sz; // ok, array_size1是sz的一個(gè)const副本
	int arr2[product(2, 3)] = { 1, 2, 3, 4, 5, 6 };
	std::cout << "arr2[5]:" << arr2[5] << "\n"; // arr2[5]:6
	return 0;
}

      constexpr構(gòu)造函數(shù):盡管構(gòu)造函數(shù)不能是const的,但是字面值常量類的構(gòu)造函數(shù)可以是constexpr函數(shù)。事實(shí)上,一個(gè)字面值常量類必須至少提供一個(gè)constexpr構(gòu)造函數(shù)。

      constexpr構(gòu)造函數(shù)可以聲明成=default的形式(或者是刪除函數(shù)的形式=delete)。否則,constexpr構(gòu)造函數(shù)就必須既符合構(gòu)造函數(shù)的要求(意味著不能包含返回語句),又符合constexpr函數(shù)的要求(意味著它能擁有的唯一可執(zhí)行語句就是返回語句)。綜合這兩點(diǎn)可知,constexpr構(gòu)造函數(shù)體一般來說應(yīng)該是空的。我們通過前置關(guān)鍵字constexpr就可以聲明一個(gè)constexpr構(gòu)造函數(shù)了。

      constexpr構(gòu)造函數(shù)必須初始化所有數(shù)據(jù)成員,初始值或者使用constexpr構(gòu)造函數(shù),或者是一條常量表達(dá)式。

      constexpr構(gòu)造函數(shù)用于生成constexpr對象以及constexpr函數(shù)的參數(shù)或返回類型。

      以下為測試代碼:

namespace {
class Debug {
public:
	// constexpr構(gòu)造函數(shù)必須初始化所有數(shù)據(jù)成員
	constexpr Debug(bool b = true) noexcept : hw_(b), io_(b), other_(b) {}
	constexpr Debug(bool h, bool i, bool o) noexcept : hw_(h), io_(i), other_(o) {}
	constexpr bool any() const noexcept { return hw_ || io_ || other_; }
	constexpr bool get_hw() const noexcept { return hw_; }
	constexpr bool get_io() const noexcept { return io_; }
	constexpr bool get_other() const noexcept { return other_; }
	void set_hw(bool b) noexcept { hw_ = b; }
	void set_io(bool b) noexcept { io_ = b; }
	void set_other(bool b) noexcept { other_ = b; }
	//constexpr void set_hw(bool b) noexcept { hw_ = b; } // C++14
	//constexpr void set_io(bool b) noexcept { io_ = b; }
	//constexpr void set_other(bool b) noexcept { other_ = b; }
private:
	bool hw_, io_, other_;
};
constexpr Debug hw_debug(const Debug& d1, const Debug& d2) noexcept
{
	return d1.get_hw() && d2.get_hw(); // 調(diào)用constexpr成員函數(shù)
}
} // namespace
int test_constexpr_2()
{
	constexpr Debug debug(false, true, false);
	if (debug.any())
		std::cout << "any true" << std::endl; // will output
	if (debug.get_io())
		std::cout << "get_io true" << "\n"; // will output
	constexpr Debug prod(false);
	if (prod.any())
		std::cout << "any true" << std::endl; // will not output
	constexpr auto hw = hw_debug(debug, prod); // 使用constexpr函數(shù)的結(jié)果來初始化constexpr對象
	std::cout << "hw:" << hw.get_hw() << "\n"; // hw:0
	return 0;
}

      注:以上內(nèi)容主要整理自:《C++ Primer Fifth Edition》、《Effective Modern C++》

      C++14中constexpr的使用

      在C++11中,constexpr函數(shù)只能包含一組非常有限的語法,包括但不限于:typedefs、using和一條返回語句。在C++14中,允許的語法集大大擴(kuò)展,包括最常見的語法,如if語句、多次返回、while或for循環(huán)等。

      以下為測試代碼:

namespace {
// C++14 constexpr functions may use local variables and loops
constexpr int pow2(int base, int exp) noexcept
{
	auto result = 1;
	for (int i = 0; i < exp; ++i) result *= base;
	return result;
}
constexpr unsigned int factorial(unsigned int n) {
	if (n <= 1)
		return 1;
	else
		return n * factorial(n - 1);
}
} // namespace
int test_constexpr_14_1()
{
	constexpr auto value = pow2(2, 4);
	std::cout << "pow2 value:" << value << "\n"; // pow2 value:16
	constexpr auto value2 = factorial(5);
	std::cout << "factorial value:" << value2 << "\n"; // factorial value:120
	return 0;
}

      執(zhí)行結(jié)果如下:

      GitHub:https://github.com/fengbingchun/Messy_Test

到此這篇關(guān)于C++11/C++14中constexpr的使用的文章就介紹到這了,更多相關(guān)C++ constexpr使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語言判斷字符串長度的方法小結(jié)

    C語言判斷字符串長度的方法小結(jié)

    學(xué)過C/C++的人都知道,在C/C++中并沒有提供直接獲取數(shù)組長度的函數(shù),對于存放字符串的字符數(shù)組提供了一個(gè)strlen函數(shù)獲取其長度,那么對于其他類型的數(shù)組如何獲取他們的長度呢?本文給大家介紹了C語言判斷字符串長度的方法小結(jié),需要的朋友可以參考下
    2024-08-08
  • C++使用LibCurl實(shí)現(xiàn)Web隱藏目錄掃描功能

    C++使用LibCurl實(shí)現(xiàn)Web隱藏目錄掃描功能

    LibCurl是一個(gè)開源的免費(fèi)的多協(xié)議數(shù)據(jù)傳輸開源庫,該框架具備跨平臺(tái)性,開源免費(fèi),并提供了包括HTTP、FTP、SMTP、POP3等協(xié)議的功能,本文將給大家介紹C++使用LibCurl實(shí)現(xiàn)Web隱藏目錄掃描功能
    2023-11-11
  • 解析OpenSSL1.1.1?centos7安裝編譯aes的c++調(diào)用

    解析OpenSSL1.1.1?centos7安裝編譯aes的c++調(diào)用

    這篇文章主要介紹了OpenSSL1.1.1?centos7安裝編譯aes的c++調(diào)用,實(shí)現(xiàn)方法也很簡單,主要是在該文檔內(nèi)加入openssl的lib路徑,感興趣的朋友跟隨小編一起看看吧
    2022-03-03
  • C語言動(dòng)態(tài)內(nèi)存分配和內(nèi)存操作函數(shù)使用詳解

    C語言動(dòng)態(tài)內(nèi)存分配和內(nèi)存操作函數(shù)使用詳解

    但是在實(shí)際的編程中,往往會(huì)發(fā)生這種情況,即所需的內(nèi)存空間取決于實(shí)際輸入的數(shù)據(jù),而無法預(yù)先確定 。為了解決上述問題,C語言提供了一些內(nèi)存管理函數(shù),這些內(nèi)存管理函數(shù)可以按需要?jiǎng)討B(tài)的分配內(nèi)存空間,也可把不再使用的空間回收再次利用
    2022-12-12
  • 用C語言實(shí)現(xiàn)猜數(shù)字

    用C語言實(shí)現(xiàn)猜數(shù)字

    這篇文章主要為大家詳細(xì)介紹了用C語言實(shí)現(xiàn)猜數(shù)字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • C語言中system()函數(shù)的用法總結(jié)

    C語言中system()函數(shù)的用法總結(jié)

    system()函數(shù)功能強(qiáng)大。以下小編就為大家介紹一下在C語言中system()函數(shù)的用法。需要的朋友可以過來參考下,希望對大家有所幫助
    2013-10-10
  • 淺析_tmain()與main()的區(qū)別

    淺析_tmain()與main()的區(qū)別

    _tmain()是為了支持unicode所使用的main一個(gè)別名,既然是別名,應(yīng)該有宏定義過的,在哪里定義的呢?就在那個(gè)讓你困惑的<stdafx.h>里
    2013-03-03
  • C++語法中的函數(shù)重載和默認(rèn)參數(shù)

    C++語法中的函數(shù)重載和默認(rèn)參數(shù)

    這篇文章主要介紹了C++語法中的函數(shù)重載和默認(rèn)參數(shù),本文從語法角度通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • C++實(shí)現(xiàn)LeetCode(208.實(shí)現(xiàn)字典樹(前綴樹))

    C++實(shí)現(xiàn)LeetCode(208.實(shí)現(xiàn)字典樹(前綴樹))

    這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(208.實(shí)現(xiàn)字典樹(前綴樹)),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼的解決

    vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼的解決

    本文主要介紹了vscode編譯運(yùn)行c語言報(bào)錯(cuò)亂碼,文中通過圖文介紹的的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07

最新評論

华蓥市| 曲阜市| 修文县| 南充市| 锡林浩特市| 威宁| 乌兰浩特市| 曲靖市| 黄龙县| 福海县| 宜良县| 濉溪县| 海南省| 阜南县| 万安县| 济南市| 左贡县| 松江区| 长丰县| 南丰县| 大宁县| 醴陵市| 宿松县| 青岛市| 读书| 宁阳县| 邵武市| 尖扎县| 东山县| 嵩明县| 榆中县| 彭阳县| 内江市| 黔西县| 银川市| 疏附县| 白银市| 巫山县| 泸州市| 康马县| 邹城市|