Skip to content
/ CPP Public

Learning modern C++ concepts ( C++14, C++17, C++20 )

Notifications You must be signed in to change notification settings

doorcs/CPP

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๊ธฐ์–ตํ•ด์•ผ ํ•  ๋‚ด์šฉ๋“ค

  • getline() ์‚ฌ์šฉ ์ „์— cin ๊ฐ์ฒด๋ฅผ ํ†ตํ•œ ์ž…๋ ฅ์„ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด cin.ignore() ๊ผญ ํ•ด์ฃผ๊ธฐ
    int N; cin >> N;
    cin.ignore()
    string s; getline(cin, s);
  • char ํƒ€์ž…์˜ ์ˆซ์ž๋ฅผ ์ •์ˆ˜ํ˜•์œผ๋กœ ๋ณ€ํ™˜
    char character = '1';
    int integer = character-'0'; // float, double, long, long long ๋ชจ๋‘ ๊ฐ€๋Šฅ (์ •์ˆ˜ ๊ฐ’์ด ์บ์ŠคํŒ…๋˜๋Š”๊ฒƒ)
  • vector๋ฅผ ํ™œ์šฉํ•œ ์ด์ฐจ์› ๋ฐฐ์—ด ๋งŒ๋“ค๊ธฐ
    int COL = ์„ธ๋กœ๊ธธ์ด(์—ด), ROW = ๊ฐ€๋กœ๊ธธ์ด(ํ–‰)
    vector<vector<int>> brd(COL, vector<int>(ROW)); // `vector<T> vector(size, val=T())`๋ฅผ ์ค‘์ฒฉ
  • fill()์„ ํ™œ์šฉํ•ด ์ฃผ์–ด์ง„ ๋ฒกํ„ฐ๋‚˜ ๋ฐฐ์—ด์„ ์ดˆ๊ธฐํ™” (์ผ๋ถ€ ์ˆ˜์ •๋„ ๊ฐ€๋Šฅ)
    fill(iter, iter, val);
    // ์ดํ„ฐ๋ ˆ์ดํ„ฐ ๋‘ ๊ฐœ๋ฅผ ๋ฐ›์•„์„œ, [inclusive, exclusive) ์˜์—ญ์— val์„ ์ฑ„์šด๋‹ค
    
    int arr[3] = {3, 6, 9}; // ์ƒˆ๋กœ ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ๋ฒกํ„ฐ๋ฅผ ์“ฐ๋ฉด ๋˜๋Š”๋ฐ, ๋ฌธ์ œ์—์„œ ๋ฐฐ์—ด์ด ์ฃผ์–ด์ง€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค
    fill(arr, arr+3, 0); // arr = {0, 0, 0}
    
    vector<int> vec(7, 3);
    fill(vec.begin()+2, vec.begin()+5, 6); // vec = {3, 3, 6, 6, 6, 3, 3}
  • stringstream ํด๋ž˜์Šค์™€ getline() ํ•จ์ˆ˜๋ฅผ ํ™œ์šฉํ•œ split
    string str = "hello, world!";
    stringstream ss(str);
    while (getline(ss, str, ' ')) {
      cout << str << '\n'; // str ๋ณ€์ˆ˜๋ฅผ ์žฌํ™œ์šฉ
      // getline() ํ•จ์ˆ˜์˜ ์„ธ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” `๋ฐ˜๋“œ์‹œ` char ํƒ€์ž…์ด์–ด์•ผ ํ•จ (๋ณต์žกํ•œ delim ๋ถˆ๊ฐ€)
    }
  • split() ๊ตฌํ˜„์ฒด
    vector<string> split(string str, string delim) {
      str.erase(str.find_last_not_of(" \t\n\r\f\v")+1); // ๋’ค์ชฝ ๊ณต๋ฐฑ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ right-trim
      vector<string> ret;
      size_t fr = 0, rr = str.find(delim); // ๊ธฐ๋Šฅ์  ์ฐจ์ด๋Š” ์—†์ง€๋งŒ int๋ฅผ ์“ฐ๋ฉด ์ปดํŒŒ์ผ warning
      while (rr != string::npos) {
        if (fr != rr) ret.push_back(str.substr(fr, rr - fr)); // delim์ด ์—ฐ๋‹ฌ์•„ ๋‚˜์˜ค๋Š” ์ผ€์ด์Šค ๋Œ€์‘
        fr = rr + delim.size();
        rr = str.find(delim, fr);
      }
      ret.push_back(str.substr(fr)); // delim์ด ํ•˜๋‚˜๋„ ์—†์„ ๊ฒฝ์šฐ ์ „์ฒด๋ฅผ, ์žˆ๋‹ค๋ฉด ๋งˆ์ง€๋ง‰ ๋ฉ์–ด๋ฆฌ๋ฅผ ๋‹ด์•„์คŒ
      return ret;
    } // delimiter๋กœ ๋‹ค์–‘ํ•œ ํ˜•ํƒœ์˜ ๋ฌธ์ž์—ด์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
  • ๋น„ํŠธ๋งˆ์Šคํ‚น ๋ฐฐ์—ด๊ณผ next_permutation()์„ ํ™œ์šฉํ•œ ์กฐํ•ฉ ์ฐพ๊ธฐ
    vector<int> num{1, 2, 3, 4, 5, 6, 7, 8, 9}, idx{0, 0, 0, 0, 0, 1, 1, 1, 1}; // 0 ๋จผ์ € ์จ์•ผํ•จ!
    
    do {
      for (int i = 0; i < 9; i++)
        if (idx[i])
          cout << num[i] << ' '; // {6, 7, 8, 9}์—์„œ {1, 2, 3, 4}๊นŒ์ง€์˜ ๋ชจ๋“  ์กฐํ•ฉ์„ `์—ญ์ˆœ`์œผ๋กœ
      cout << '\n';
    } while (next_permutation(idx.begin(), idx.end()));  
  • ๋ฒ”์œ„ ๊ธฐ๋ฐ˜ for๋ฌธ์„ ํ™œ์šฉํ•œ ์ž…์ถœ๋ ฅ ์ฒ˜๋ฆฌ
    vector<int> vec1(3);
    for (int& it : vec1) cin >> it; // ์ž…๋ ฅ ์ฒ˜๋ฆฌ์—๋Š” `&`๋ฅผ ๋ถ™์—ฌ์•ผ ํ•จ (reference variable)
    for (int it : vec1) cout << it << '\n'; // for (auto it : vec1) cout << it << '\n';
    
    vector<pair<int, int>> vec2(5);
    for (auto& [a, b] : vec2) cin >> a >> b; // (C++17) structured binding - ์•ž์— auto ๋ถ™์—ฌ์ฃผ๊ธฐ!!
    for (const auto [a, b] : vec2) cout << a << ' ' << b << '\n'; // ์ถœ๋ ฅ์€ `&`๊ฐ€ ์—†์–ด๋„ ๋จ
  • <algorithm> ํ—ค๋” ์ œ๊ณต ํ•จ์ˆ˜๋“ค์—์„œ initializer_list ํด๋ž˜์Šค{} ํ™œ์šฉ
    int val1 = 9999, val2 = 3210, val3 = -2147483648;
    cout << min({val1, val2, val3}) << ' ' << max({val1, val2, val3});
    // cout << min(val1, min(val2, val3)) << ' ' << max(val1, max(val2, val3));
  • ๋น„ํŠธ ์—ฐ์‚ฐ์ž๋ฅผ ํ™œ์šฉํ•œ ํšจ์œจ์ ์ธ ํ™€์ˆ˜ / ์ง์ˆ˜ ํŒ๋ณ„
    int even = 2, odd = 3;
    if (odd&1) cout << "odd"; // ํ™€์ˆ˜์™€ &1ํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ’์ด 1, true (๋น„ํŠธํŒจํ„ด์€ ๋งˆ์ง€๋ง‰ ๋น„ํŠธ๋งŒ 1)
    if (!(even&1)) cout << "even"; // ์ง์ˆ˜์™€ &1 ํ•˜๋ฉด ๊ฒฐ๊ณผ๊ฐ’์ด 0, false (๋น„ํŠธํŒจํ„ด์€ ๋ชจ๋“  ๋น„ํŠธ๊ฐ€ 0)
    // ์ง์ˆ˜ ํŒ์ •์€ ๋ฐ˜๋“œ์‹œ ๋‘ ๋ฒˆ ์ด์ƒ์˜ ์—ฐ์‚ฐ์ด ํ•„์š”ํ•˜์ง€๋งŒ, ํ™€์ˆ˜ ํŒ์ •์€ `&1`๋กœ ํ•œ ๋ฒˆ์˜ ์—ฐ์‚ฐ์— ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค

STL ์ปจํ…Œ์ด๋„ˆ ์‚ฌ์šฉ๋ฒ• ์ •๋ฆฌ

  • ์ปจํ…Œ์ด๋„ˆ ๊ณตํ†ต:

    • .size() ๋ฉ”์„œ๋“œ๋กœ ํ˜„์žฌ ๋‹ด์•„๋‘๊ณ  ์žˆ๋Š” ์š”์†Œ์˜ ์ˆ˜๋ฅผ ์•Œ ์ˆ˜ ์žˆ์Œ
    • .empty() ๋ฉ”์„œ๋“œ๋กœ ํ˜„์žฌ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋น„์–ด์žˆ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ์Œ
    • ์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑ ์‹œ์ ์— ๊ฐ’๋“ค์„ ๋ชจ๋‘ ์•Œ ์ˆ˜ ์žˆ๋‹ค๋ฉด, initializer_list ์ƒ์„ฑ์ž๋ฅผ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ์Œ
  • ๋ฌธ์ž์—ด ( std::string )

    string str;
    // cin >> str; // cin์„ ํ†ตํ•œ ์ž…๋ ฅ๋„ ๊ฐ€๋Šฅ
    // cin.ignore() <<- ์ž…๋ ฅ ์ฒ˜๋ฆฌ์— cin ๊ฐ์ฒด๋ฅผ ํ™œ์šฉํ–ˆ๋‹ค๋ฉด, getline() ํ•จ์ˆ˜ ์‚ฌ์šฉ ์ „์— cin.ignore() ํ•„์š”
    getline(cin, str); // getline() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด, ๊ณต๋ฐฑ์„ ํฌํ•จํ•œ ํ•œ ์ค„ ์ž…๋ ฅ์„ string์— ๋‹ด์„ ์ˆ˜ ์žˆ๋‹ค
    // std::getline() ํ•จ์ˆ˜๋Š” <string> ํ—ค๋”์— ์žˆ๋‹ค!
    
    // ์ž๋ฅด๊ธฐ ( Substring )
    string sub = str.substr(start, count); // start ์ธ๋ฑ์Šค๋กœ๋ถ€ํ„ฐ count๊ฐœ๋ฅผ ์„ ํƒํ•œ substring
    // str.substr(0, 3); <<- {0๋ฒˆ์งธ, 1๋ฒˆ์งธ, 2๋ฒˆ์งธ} ์ธ๋ฑ์Šค, ์ฆ‰ {์ฒซ๋ฒˆ์งธ, ๋‘๋ฒˆ์งธ, ์„ธ๋ฒˆ์งธ} ๋ฌธ์ž๋ฅผ ๋‹ด์•„ return
    
    // ์˜ค๋ฅธ์ชฝ ๊ณต๋ฐฑ ์ œ๊ฑฐ ( Right Trim )
    str.erase(str.find_last_not_of(" \t\n\r\f\v") + 1);
    // str.erase(find_last_not_of("0x20 | 0x09 | 0x0a | 0x0d | 0x0c | 0x0b")+1);
    // find_last_not_of()๋Š” ๋ฌธ์ž์—ด์ด ๋ชจ๋‘ ๊ณต๋ฐฑ์ผ ๊ฒฝ์šฐ string::npos๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ +1์„ ํ•ด์ฃผ๋ฉด 0์ด ๋˜๋Š”๋ฐ,
    // str.erase(0)์€ str.erase(0, string::npos)์™€ ๊ฐ™๊ณ , ๋ฌธ์ž์—ด์„ ๋ชจ๋‘ ์ง€์šด๋‹ค
      
    // ์™ผ์ชฝ ๊ณต๋ฐฑ ์ œ๊ฑฐ ( Left Ttrim )
    str.erase(0, str.find_first_not_of(" \t\n\r\f\v"));
    // find_first_not_of()๋Š” ๋ฌธ์ž์—ด์ด ๋ชจ๋‘ ๊ณต๋ฐฑ(whitespace character)์ผ ๊ฒฝ์šฐ string::npos๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ
    // str.erase(0, string::npos)๊ฐ€ ํ˜ธ์ถœ๋˜์–ด ๋ฌธ์ž์—ด์„ ๋ชจ๋‘ ์ง€์šด๋‹ค
  • ๋งต ( std::map )

    map<T, U> mp; // map<T, U> mp{{key1, val1}, {key2, val2}};
    // key-value ๋งคํ•‘์— ์‚ฌ์šฉํ•จ. ๋‚ด๋ถ€์ ์œผ๋กœ pair<T, U>๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ key์˜ `operator<`๋ฅผ ์ ์šฉํ•ด ์˜ค๋ฆ„์ฐจ์ˆœ์œผ๋กœ ์ •๋ ฌํ•จ
    mp[key] = val; // ์กด์žฌํ•˜์ง€ ์•Š๋Š” key์— ์ ‘๊ทผํ•˜๋ฉด U์˜ ๊ธฐ๋ณธ ์ƒ์„ฑ์ž๊ฐ€ ํ˜ธ์ถœ๋˜์–ด {key, val} ์Œ์„ map์— insertํ•จ
    mp[key]++; // map<int, int>์ผ ๊ฒฝ์šฐ, {key, 0} -> `++` -> ์ตœ์ข…์ ์œผ๋กœ {key, 1}๊ฐ€ map์— insert๋จ
    .find(key); // find ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํŠน์ • key์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ - ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ .end() ๋ฐ˜ํ™˜
    // .contains() ๋ฉ”์„œ๋“œ๊ฐ€ ๋” ์ง๊ด€์ ์ด์ง€๋งŒ, C++20 feature์ด๋ฏ€๋กœ find ๋ฉ”์„œ๋“œ์— ์ต์ˆ™ํ•ด์ง€๊ธฐ
  • ํ•ด์‹œ๋งต ( std::unordered_map )

    unordered_map<T, U> mp; // unordered_map<T, U> mp{{key1, val1}, {key2, val2}};
    // map๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ Hashing ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ด ์š”์†Œ ์ ‘๊ทผ์˜ ์‹œ๊ฐ„๋ณต์žก๋„๊ฐ€ O(1)
    // ๋‹จ, key๋กœ ์‚ฌ์šฉํ•  ํƒ€์ž…์€ ๋ฐ˜๋“œ์‹œ 1. hash function, 2. equality check ๋‘๊ฐ€์ง€๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์–ด์•ผ ํ•จ
    // primitive types, string ์ •๋„๋งŒ key๋กœ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹์„ ๋“ฏ (์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ์ฒด๋ฅผ key๋กœ ์“ฐ๋ ค๋ฉด ๊ท€์ฐฎ๋‹ค)
  • ์…‹ ( std::set )

    set<T> s; // set<T> s{val1, val2, val3};
    // ํฌํ•จ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•ด์•ผ ํ•  ๋•Œ ์‹œ๊ฐ„๋ณต์žก๋„๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์›์†Œ๋“ค์˜ uniqueness๋ฅผ ๋ณด์žฅ
    .insert(val); // insert ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ๊ฐ’์„ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  `์‹œ๋„`ํ•  ์ˆ˜ ์žˆ์Œ - ๊ฐ’์ด ์ด๋ฏธ ์กด์žฌํ•  ๊ฒฝ์šฐ ๋ฌด์‹œ๋จ
    .find(val); // find ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ํŠน์ • ๊ฐ’์˜ ์กด์žฌ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Œ - ์กด์žฌํ•˜์ง€ ์•Š์„ ๊ฒฝ์šฐ .end() ๋ฐ˜ํ™˜
  • ๋ฆฌ์ŠคํŠธ ( std::list )

    list<T> li; // list<T> li{val1, val2, val3};
    // [] ์—ฐ์‚ฐ์ž๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š์•„, ์š”์†Œ๋ฅผ ๋‹ค๋ฃฐ ๋•Œ iterator๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•จ
    // .begin() ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐฉ์‹์ด ๊ฐ€์žฅ ์ง๊ด€์ ์ž„
    auto it = li.begin();
    cout << *it; // ์ฒซ๋ฒˆ์งธ ์š”์†Œ ์ฐธ์กฐ
    for (int i = 0; i < N; i++) it++; // advance(it, N) ์™€ ๊ฐ™๋‹ค
    cout << *it; // N+1๋ฒˆ์งธ ์š”์†Œ ์ฐธ์กฐ (N์ด 2์ผ ๊ฒฝ์šฐ, 3๋ฒˆ์งธ ์š”์†Œ ์ฐธ์กฐ)
    
    .insert(pos, val); // ์ด๋•Œ pos๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ. ์ƒˆ๋กœ ๋“ค์–ด์˜จ ์›์†Œ๊ฐ€ pos๋ฒˆ์งธ ์›์†Œ๊ฐ€ ๋จ
    .erase(pos); // ์‚ญ์ œ๋œ ์›์†Œ ๋‹ค์Œ ์›์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ์ดํ„ฐ๋ ˆ์ดํ„ฐ๋ฅผ returnํ•จ. insert์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ
    li.insert(li.erase(it), val); // it์ž๋ฆฌ์— ์›๋ž˜ ์žˆ๋˜ ์›์†Œ๋ฅผ ์‚ญ์ œํ•˜๊ณ , val๋กœ ๋Œ€์ฒดํ•จ
  • ๋ฒกํ„ฐ, ๋™์  ๋ฐฐ์—ด ( std::vector )

    vector<T> v; // vector<T> v{val1, val2, val3};
    // ๋™์  ๋ฐฐ์—ด. ์ƒ์„ฑ์ž๋ฅผ ํ˜ธ์ถœ ์‹œ ํฌ๊ธฐ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ธฐ๋ณธ size์™€ capacity๋Š” ๋ชจ๋‘ 0
    // push_back(), pop_back(), back() ์„ธ๊ฐ€์ง€ ์—ฐ์‚ฐ์œผ๋กœ ์Šคํƒ์„ ๋Œ€์ฒดํ•  ์ˆ˜ ์žˆ์Œ (๊ธฐ๋Šฅ์ด ๋” ๋งŽ์•„์„œ ํŽธ๋ฆฌํ•˜๋‹ค)
    .push_back(val); // ํ˜„์žฌ ์š”์†Œ๋“ค์˜ ๋์— ์ถ”๊ฐ€. stack.push() ๋Œ€์ฒด ๊ฐ€๋Šฅ
    .pop_back(); // stack.pop() ๋Œ€์ฒด ๊ฐ€๋Šฅ
    .back(); // stack.top() ๋Œ€์ฒด ๊ฐ€๋Šฅ
    // .insert(pos, val) - insert ์—ฐ์‚ฐ์ด ํ•„์š”ํ•  ๊ฒฝ์šฐ vector ๋Œ€์‹  list ์“ฐ๊ธฐ
    vector<int> v(10);
    for (int& it : v) cin >> it; // for (auto& it : v) ๋„ ๊ฐ€๋Šฅ
  • ๋ฑ ( std::deque )

    deque<T> dq;
    .push_front(val);
    .pop_front();
    .push_back();
    .pop_back();
    // ๋’ค์ง‘๋Š” ์—ฐ์‚ฐ์ด ํ•„์š”ํ•  ๋•Œ, ์‹ค์ œ๋กœ ์ˆœ์„œ๋ฅผ ๋’ค์ง‘๋Š” ๋Œ€์‹  ๋ฐ˜๋Œ€๋กœ ์ˆœํšŒํ•˜๋„๋ก ํ•  ์ˆ˜ ์žˆ๋‹ค
  • ํ ( std::queue )

    queue<T> q;
    .front();
    .push(val);
    .pop();
  • ์šฐ์„ ์ˆœ์œ„ ํ ( std::priority_queue )

    priority_queue<T> pq;
    .top(); // .front()๊ฐ€ ์•„๋‹ˆ๋ผ .top()์ด๋‹ค! top priority!!
    .push();
    .pop();

์–ธ์  ๊ฐ€ ๊ณ ์ณค๋˜ ์ข‹์ง€ ์•Š์€ ์Šต๊ด€๋“ค

  • ์ค„๋ฐ”๊ฟˆ์ด ํ•„์š”ํ•  ๋• std::endl ๋Œ€์‹  '\n' ์‚ฌ์šฉ
  • cin.tie(nullptr)->ios_base::sync_with_stdio(false); ์ฒ˜๋Ÿผ ์“ฐ์ง€ ๋ง๊ณ  ๋ถ„๋ฆฌํ•˜๊ธฐ
      cin.tie(nullptr);
      cout.tie(nullptr);
      ios_base::sync_with_stdio(false);
  • for, while ๊ฐ™์€ ์ œ์–ด๋ฌธ ํ‚ค์›Œ๋“œ์™€ ์กฐ๊ฑด์‹ ๊ด„ํ˜ธ ์‚ฌ์ด๋Š” ํ•œ ์นธ ๋„์›Œ์ฃผ๊ธฐ
      for(;;) // bad
      for (;;) // good!
  • if, else if, else ๊ตฌ๋ฌธ ์ •๋ ฌ - closing brace on new line, else on same line
      if (cond1) {
        // 
      } else if (cond2) { // good!  
        //
      } else {
        //
      }

About

Learning modern C++ concepts ( C++14, C++17, C++20 )

Topics

Resources

Stars

Watchers

Forks

Languages