ちょっと間が空いて久しぶりのC++17。
今回もライブラリ関連。
・範囲から指定された個数の要素をランダムに抽出する
std::sample
ランダムといえばC++11でライブラリrandomが追加されて
| 1 2 3 4 5 6 7 8 9 | #include <iostream> # include <random> int main() {     std::random_device rd;     std::mt19937 mt(rd());     std::cout << mt() << '\n'; } | 
こんなのが使えるようになりました。
範囲指定であれば
| 1 | std::uniform_int_distribution<> rand100(0, 99); | 
今回のsampleは範囲から指定された個数を抽出になります。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | int main() {     std::random_device rd;     std::mt19937 mt(rd());     std::vector<std::string> color{"red","blue","green","yellow","white","black","pink","orange","purple","gold"};     const int choice_count = 2;     std::vector<std::string> result;     std::sample(color.begin(),                 color.end(),                 std::back_inserter(result),                 choice_count,                 mt);     for(auto n : result){         std::cout << n << std::endl;     } } | 
ちなみに計算量は範囲の数に対して線形時間O(n)になるのでお気を付けを。
・左辺値参照をconst左辺値参照にする
std::as_const
constは意図しないデータ変更を防ぐ、constがついていれば変更しないデータであることがわかります。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <iostream> #include <utility> class SampleA { public:   void func()   {     std::cout << "こちらは非const" << std::endl;   }   void func() const   {     std::cout << "こちらはconst" << std::endl;   } }; int main() {   SampleA a;   a.func();   std::as_const(a).func();   const SampleA b;   b.func(); } | 
結果は
| 1 2 3 | こちらは非const こちらはconst こちらはconst | 
となります。
上記上記の例ではメンバー関数でconst版、非const版が存在しているものです。
const宣言していないオブジェクトaは呼び出したときに非constの関数が呼ばれていて、
そのあとas_constによってconst版が呼ばれています。
as_constを使用することによってキャストしたり、const版を呼ぶための実装がすっきりします。
・任意個数の引数をとってbool型を返す関数オブジェクトを受け取り、戻り値を論理反転する関数オブジェクトに変換する
std::not_fn
論理反転なので
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #include <iostream> #include <functional> bool func1(int a) {   if(a == 0){       return true;   }   return false; } int main() {   std::cout << std::boolalpha;   auto func = std::not_fn(func1);   std::cout << func(1) << std::endl;   std::cout << func(0) << std::endl; } | 
上記の例でfuncの関数オブジェクトが反転されるので引数が0の場合はfalse、それ以外がtrueとなっています。
ちなみにstd::not_fnの追加に伴い以下の関数が非推奨になります。
・std::not1()
・std::not2()
こんなのあったのか..
短いですが今回はこれまで。
過去分
C++17を知るその1
C++17を知るその2
C++17を知るその3
C++17を知るその4
C++17を知るその5
C++17を知るその6



