C++11以降。
たまにしか書かないけどたまに書こうとしてハマりがちな文法など。
- Wandbox : なぜか名前の覚えられないオンラインコンパイラ
template
template実装の隠蔽
templateも宣言のみヘッダで公開、実装はCPPに隠蔽とすることができる。
hoge.hpp
template <typename T> int Hoge(); //宣言
hoge.cpp
template <typename T> int Hoge() { return 1; } //定義
template int Hoge<int>(); //上の定義をそのまま使う実体化
template <> int Hoge<float>() { return 2; } //特殊化
main.cpp
Hoge<int>(); //-> 1
Hoge<float>(); //-> 2
Hoge<double>(); //-> undefined reference
テンプレートテンプレートパラメータ
コンテナ自体をテンプレート引数にする。
C++17以前ではtypenameキーワード使用不可(下のコードのclass Container
のclassの部分)。
参考: テンプレートテンプレートパラメータにtypenameキーワードの使用を許可 - cpprefjp
template <template <typename> class Container>
size_t GetSize(const Container<int>& c)
{
return c.size();
}
const size_t sizeOfVector = GetSize(std::vector<int>{1,2,3});
const size_t sizeOfList = GetSize(std::list<int>{4,5});
emplaceで引数が一つでないコンストラクタを呼ぶ
piecewise_constructがいつも思い出せない。
std::unordered_map<Foo, Bar> map;
map.emplace(
std::piecewise_construct,
std::forward_as_tuple(1, 2, 3), //引数2つ以上のコンストラクタ
std::forward_as_tuple()); //引数なしコンストラクタ
その他
UTF-8ヒアドキュメント
u8R"(
と)"
で括る。
const char* const json = u8R"({
"issue": {
"project_id": 1,
"subject": "test1",
"tracker_id": 1,
"description": "message"
}
})";
クロージャ(closure)
コピーキャプチャしてmutable指定して変更する。
int count = 0;
auto closure = [count]() mutable { ++count; return count; };
closure(); //->1
closure(); //->2
結局main関数はどう書けばいいのか
原則として以下の2パターン。
引数にconstを付けたくなるけど我慢する。
main 関数 - cppreference.com
main.cpp
int main() { return 0; }
main.cpp
int main(int argc, char *argv[]) { return 0; }
move pImpl
moveするときは参照の更新を忘れないこと。
Hoge.hpp
class Hoge
{
public:
Hoge(Hoge&& source);
//move代入演算子も同様
private:
class Impl;
std::unique_ptr<Impl> impl; //非公開実装
};
Hoge.cpp
class Hoge::Impl
{
public:
Hoge* hoge;
Impl(Hoge* const hoge) : hoge(hoge) {}
};
Hoge::Hoge(Hoge&& source)
: impl(std::move(source.impl))
{
impl->hoge = this; //忘れずに更新する
}