前言
個人向記錄,不全,有生之年,以上。
- 2024/12/09 首次更新
constexpr:常量表示式
constexpr最重要的意義是編譯器最佳化,比如做模板型別推斷時
constexpr:常量表示式,是一種編譯器最佳化的手段
參考:https://www.cnblogs.com/fuzhe1989/p/3554345.html
constexpr是C++11中新增的關鍵字,其語義是“常量表示式”,也就是在編譯期可求值的表示式。最基礎的常量表示式就是字面值或全域性變數/函式的地址或sizeof等關鍵字返回的結果,而其它常量表示式都是由基礎表示式透過各種確定的運算得到的。constexpr值可用於enum、switch、陣列長度等場合。
constexpr所修飾的變數一定是編譯期可求值的,所修飾的函式在其所有引數都是constexpr時,一定會返回constexpr。
constexpr int Inc(int i) {
return i + 1;
}
constexpr int a = Inc(1); // ok
constexpr int b = Inc(cin.get()); // !error
constexpr int c = a * 2 + 1; // ok
constexpr還能用於修飾類的建構函式,即保證如果提供給該建構函式的引數都是constexpr,那麼產生的物件中的所有成員都會是constexpr,該物件也就是constexpr物件了,可用於各種只能使用constexpr的場合。注意,constexpr建構函式必須有一個空的函式體,即所有成員變數的初始化都放到初始化列表中。
struct A {
constexpr A(int xx, int yy): x(xx), y(yy) {}
int x, y;
};
constexpr A a(1, 2);
enum {SIZE_X = a.x, SIZE_Y = a.y};
但是,也要注意,如果呼叫建構函式時有不定引數x,那麼也不會報錯,當作普通物件初始化
一個例子:
constexpr void f(){
int a = 0;
int * p = &a; // 對
}
static int b = 0;
int main(){
int a = 0;
constexpr int * p = &a; // 錯,棧上變數的地址編譯期是不能確定的
constexpr int * q = &b; // 對,靜態儲存區變數的地址是編譯時就可確定的
}
inline
https://en.cppreference.com/w/cpp/language/inline
https://www.zhihu.com/question/419304773/answer/1453712022
inline曾經被用作行內函數,作為最佳化手段,但是現代c++(17及之後)並不是這樣。
inline 現在表示在連結時遇到不同編譯單元出現了相同簽名的函式時,只保留一份。
比如說,標頭檔案中定義的函式在多個源程式檔案中被呼叫,inline標明這兩個函式具有相同的簽名。inline 關鍵字告訴編譯器和連結器,這個函式可能在多個編譯單元中定義,但它們實際上是相同的函式。在連結階段,連結器只會保留一份函式定義。
#ifndef EXAMPLE_H
#define EXAMPLE_H
#include <atomic>
// function included in multiple source files must be inline
inline int sum(int a, int b)
{
return a + b;
}
// variable with external linkage included in multiple source files must be inline
inline std::atomic<int> counter(0);
#endif
-------------------------------------------
#include "example.h"
int a()
{
++counter;
return sum(1, 2);
}
-------------------------------------------
#include "example.h"
int b()
{
++counter;
return sum(3, 4);
}
noexcept
https://veitchkyrie.github.io/2020/02/24/C++-noexcept-運算子/
函式修飾符,指定不丟擲異常
#include<iostream>
void BlockThrow() noexcept {
throw 1;
}
int main(void) {
try {
BlockThrow();
} catch(...) {
std::cout << "BlockThrow Found throw" << std::endl;
}
}
==== 輸出:
terminate called after throwing an instance of 'int'
Aborted
auto
自動推導型別