C++關鍵字(持續更新ing)

真昼小天使daisuki發表於2024-12-09

前言

個人向記錄,不全,有生之年,以上。

  • 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

自動推導型別

override

相關文章