「C++」の版間の差分
(Container) |
(lambda) |
||
6行目: | 6行目: | ||
* [https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms More C++ Idioms - Wikibooks] | * [https://ja.wikibooks.org/wiki/More_C%2B%2B_Idioms More C++ Idioms - Wikibooks] | ||
== Core == | |||
=== lambda === | |||
ラムダ式 (lambda expression) は関数オブジェクトをその場で定義するための機能。無名関数。 | |||
構文 | |||
[<capture list>](<parameter list>) mutable <exception> <attribute> -> <return type> { <body> } | |||
以下は省略可能 | |||
* (): <parameter list>/mutable/<exception>/<attribute>/<return type> のどれも指定しない場合。 | |||
* mutable: キャプチャーした変数を書き換えない場合。 | |||
* <exception>: 指定しない場合。 | |||
* <attrbute>: 指定しない場合。 | |||
* -> <return type>: 型推論に任せる場合。 | |||
最小構成は以下となる。 | |||
[]{} | |||
キャプチャー | |||
ラムダ式は、ラムダ式外の変数をラムダ式内で参照可能にするキャプチャー (capture) という機能がある。[]内で指定する。 | |||
&=参照、==コピーの2個の基本指定があり、以下がある。 | |||
* &: 参照。 | |||
* =: コピー。 | |||
* &x: 変数xを参照。 | |||
* x: 変数xをコピー。 | |||
* &, x: デフォルトで参照、xのみコピー。 | |||
* =, &x: デフォルトでコピー、xのみ参照。 | |||
* this: *thisのメンバーを参照。 | |||
* this, x: *thisのメンバーを参照、xのみコピー。 | |||
== && == | == && == |
2024年1月8日 (月) 20:41時点における版
About
Core
lambda
ラムダ式 (lambda expression) は関数オブジェクトをその場で定義するための機能。無名関数。
構文
[<capture list>](<parameter list>) mutable <exception> <attribute> -> <return type> { <body> }
以下は省略可能
- (): <parameter list>/mutable/<exception>/<attribute>/<return type> のどれも指定しない場合。
- mutable: キャプチャーした変数を書き換えない場合。
- <exception>: 指定しない場合。
- <attrbute>: 指定しない場合。
- -> <return type>: 型推論に任せる場合。
最小構成は以下となる。
[]{}
キャプチャー
ラムダ式は、ラムダ式外の変数をラムダ式内で参照可能にするキャプチャー (capture) という機能がある。[]内で指定する。
&=参照、==コピーの2個の基本指定があり、以下がある。
- &: 参照。
- =: コピー。
- &x: 変数xを参照。
- x: 変数xをコピー。
- &, x: デフォルトで参照、xのみコピー。
- =, &x: デフォルトでコピー、xのみ参照。
- this: *thisのメンバーを参照。
- this, x: *thisのメンバーを参照、xのみコピー。
&&
情報源: c++ - What does T&& (double ampersand) mean in C++11? - Stack Overflow。
&&は参照の参照ではない。右辺値参照。ムーブセマンティクスで使用する。
explicit
情報源: c++のexplicit指定子の使い方まとめ|コウモリのちょーおんぱ。
explicitがあるとコピーコンストラクター (=代入) が禁止される。意図しない型変換などを抑止するらしい。
std::make_unique
情報源: c++ - make_uniqueの利点 - スタック・オーバーフロー。
unique_ptr生成時に使う。newするよりいい。処理が1回で済む。
class
interface
情報源:
- C++ インターフェースの実現方法【インタフェースクラスとダックタイピング】 | MaryCore
- More C++ Idioms/インタフェースクラス(Interface Class) - Wikibooks
C++でJavaなどのinterface (関数、staticのみの派生用クラス) 相当の実現には若干工夫が必要となる。
- 全ての関数が純粋仮想関数: virtual function() = 0
- 仮想デストラクター: virtual ~destructior()
virtualは関数にオーバーライドを許可する。
仮想デストラクターがあることで、派生先側でのデストラクター呼び出しを許容する。逆に、これがないと、該当するデストラクターが呼ばれず、メモリーリークになりえるらしい。
abstract
情報源:
- 抽象クラス - C++入門
- c++ - Can a non-virtual function be equal to 0? - Stack Overflow
- 抽象クラス(C++) - 超初心者向けプログラミング入門
抽象クラス。純粋仮想関数が1個以上存在するクラス。
ベースクラスにvirtual function() = 0;がある場合、派生クラスではvirtualは別になくてもいい。
function() = 0; で同じ意味になる。
純粋仮想関数が存在する場合、継承必須になり、そのクラスはインスタンスを生成できない。
String
Replace
std::string::replaceが基本。
文字列の特定範囲を指定文字列で置換する。破壊的操作。
std::findの検索と併用する必要がある。
その他に、algorithmのstd::replaceもある。こちらはcharg型などの1文字同士であれば全置換できる。
findと文字列単位だとwhileなど。
/// "a, b".replaceFirst(", ", "|") 相当の文字列置換 std::string s = "a, b"; std::string t = ", "; // 検索文字列 auto pos = s.find(t); // 検索文字列が見つかった位置 (pos == 1) auto len = t.length(); // 検索文字列の長さ (len == 2) if (pos != std::string::npos) { s.replace(pos, len, "|"); // s == "a|b" }
Slice
特定文字列で検索して、一部分を切り出したいことがよくある。jsonの末端など。
std::string::size_type pos = find(".");
startsWith
情報源: C++ 文字列型で前方一致の検索【std::string startsWith/hasPrefix 接頭辞判定】 | MaryCore。
std::string s = "abc"; // 検索先の文字列 std::string t = "ab"; // 検索文字列 if (s.size() >= t.size() && std::equal(std::begin(t), std::end(t), std::begin(s))) { puts("文字列`ab`で始まる文字列です"); }
Case
情報源
#include <algorithm> std::string string = ""; std::transform(string.cbegin(), string.cend(), string.begin(), std::toupper);
Container
std::pair/std::tuple
- pair - cpprefjp C++日本語リファレンス
- tuple - cpprefjp C++日本語リファレンス
- 【C++】std::pair, tupleの基本的な使い方 - osazoの技術ブログ
キーバリュー形式のデータ型。
std::pairはstd::map類の要素の型。キーバリューで一対一。std::mapは勝手にソートされる。追加順にしたかったら、自分でstd::vector<std::pair>でmapに似た構造を作るしかない。
#include <iostream> #include <utility> #include <string> int main() { // pairオブジェクトの構築 std::pair<int, std::string> p = std::make_pair(1, "hello"); // 要素の参照 std::cout << p.first << std::endl; std::cout << p.second << std::endl; }
std::tupleは一体多の型。std::pairのバリュー部分に独自の構造体を使えば似たようなことはできるが、専用の構造体が不要なのが便利。
#include <iostream> #include <tuple> #include <string> int main() { // 3要素のタプルを作る std::tuple<int, char, std::string> t = std::make_tuple(1, 'a', "hello"); // 0番目の要素を参照 int& i = std::get<0>(t); std::cout << i << std::endl; // 2番目の要素を参照 std::string& s = std::get<2>(t); std::cout << s << std::endl; }