Upgrade to Pro — share decks privately, control downloads, hide ads and more …

C++ のあれこれ

C++ のあれこれ

Kyutech大LT祭で発表した C++ LT のスライド

Avatar for 緑獺おがめ

緑獺おがめ

December 14, 2025

Other Decks in Programming

Transcript

  1. struct 緑獺おがめ { std::vector<std::string> 所属 = {"C3", "KyuteXR"}; std::array<std::string, 6>

    好きな拡張子 = { ".cpp", ".hpp", ".cc", ".hh", ".cxx", ".hxx" }; std::vector<std::string> 好きなもの = { "#ccff00", " カワウソ" } }; 自己紹介
  2. Drogon C++ で Web バックエンドが建てれる やつ. テンプレートエンジンも備えてお り,フロントも開発することができ る. めちゃくちゃ高速で,とある計測で

    は全言語の様々な Web バックエンド フレームワーク内で最速だったとい う結果も. C++ を扱えるフレームワークなど
  3. std::vector<T> , std::list<T> , std::array<T, N> を使おう!! C++ には配列を表すクラスが用意されている. std::vector<int>

    arr; std::list<int> arr; std::array<int, 10> arr; これらを扱うことで,配列に対する処理が統一できる. 例: sort std::sort(arr.begin(), arr.end()); STL を使おう
  4. C++ では,以下のようにすることで参照渡しをすることができる. 呼び出し時にも変数名のみでよい. void func(int& n){ n += 1; }

    func(num); サイズの大きい構造体など,コピーに時間のかかるものに有効. 値渡しと参照渡し
  5. std::shared_ptr<T> , std::unique_ptr<T> これらのクラスは内部にカウンタを持っており,そのカウンタが0になったときに自動 でメモリを解放してくれる. 便利マン. { std::shared_ptr<int> ptr =

    std::make_shared<int>(100); // カウンタ 1 { std::shared_ptr<int> ptr2 = ptr; // カウンタ 2 } // カウンタ 1 } // ここで解放される スマートポインタ
  6. requires を用いたより細かな制約 以下のように記述することで,特定のメンバ変数やメソッドを持つかどうかなどまで 指定することができる. template<typename T> concept vector = requires(T&

    t, const T& ct) { typename T::value_type; { t.normalized() } -> std::same_as<T>; { ct.normalized() } -> std::same_as<T>; { t.length() } -> std::floating_point; }; concept
  7. concept は C++20 から追加された機能. C++17 以前では SFINAE というテクニックを用いることで制約を実装していた. Substitution Failure

    Is Not An Error 直訳すると「置換の失敗はエラーではない」 わけわかめですね. 説明するとこれ単体でLTができるほど長くなるため,かなり割愛して説明する. SFINAE
  8. 例として,与えられた二つの変数が加算可能かどうかを判定する関数を作ってみる. template<typename lT, typename rT> auto is_addable(lT l, rT r)

    -> decltype(l + r, bool()){ return true; } auto is_addable(...) -> bool { return false; } is_addable(3, std::string("hoge")) のように加算できない型を引数として渡した 場合,上の定義の l + r の部分で加算ができないため, template の置換に失敗す る. しかし,即座にコンパイルエラーとならず,オーバーロード候補から除外される. 結果,フォールバック関数である下の定義が呼ばれ, false が返る. SFINAE
  9. SFINAE を扱う上で頻出する std::enable_if というクラスがある. これは,テンプレート引数として bool 値と任意の型を受け取る. bool が true

    の場合はメンバ型 type として第二引数の型を持つ. typename std::enable_if<true, int>::type // int 一方 false の場合は type を持たないため,コンパイルエラーとなる. typename std::enable_if<false, int>::type // Compile Error !! SFINAE ではこのエラーが発生する特性を利用する. SFINAE
  10. template< typename T, typename std::enable_if<std::is_arithmetic<T>::value, void*>::type = nullptr > class

    Point{ /* definition */ }; T が数値型ではない → std::enable_if が type を持たない → 置換失敗 これによってこの定義はオーバーロード候補から除外され,その後 Point の定義がな くなるためコンパイルエラーとなる. 制約を満たさない場合のフォールバック型を用意しておけば,そちらが定義としてよ ばれることとなる. SFINAE