c++ 小ネタ

if文内で初期化できる

if(auto i = 5 * -10 * 3; i < 0){
    std::cout << i << " < 0" << '\n';
}

(switch文も同様)

initializer_listを関数に渡す

void disp_all(std::initializer_list<int> il){
    for(auto i: il)
        std::cout << i << " ";
}

disp_all({2,4,6,8});

推測可能な場合、テンプレートの引数は省略できる

 std::vector v;               // 型がわからないのでコンパイルエラー
 std::vector vi{1,2,3};       // 推測可能
 std::vector vs{"1","2","3"}; // 推測可能

std::source_locationを使えば、FILELINEを使っていた処理を少しスマートに書ける。

void log(const std::string & msg, 
    std::source_location s = std::source_location::current()) {
    std::cout << msg 
        << " " << s.file_name() 
        << " " << s.function_name() 
        << " " << s.line() 
        << std::endl;
}

int main(){
    ...
    log("hello");
    ...
}

pairやtupleの要素をautoで受ける

auto coord = std::make_pair(10.2, 30.4);
auto[x,y] = coord;

auto t = std::make_tuple("abc", 1024, "xyz");
auto[type, length, value] = t;
std::map<int, std::string> m{{1,"abc"},{2,"def"}};
for(auto [key, value] : m)
    std::cout << std::format("key={} value={}\n", key, value)

for文内で要素を初期化

 for(std::array a{2,4,6,8}; auto i : a)
        std::cout << i << " ";

std::iota()で連番を設定

    std::array<int,10> a;
    std::iota(a.begin(), a.end(),10); // 10から始まる連番を設定
    for(auto i : a)
        std::cout << i << '\n'; 

桁数の大きい数値は'(アポストロフィー)で区切れる

int i{1'234'567'890}; // int i{1234567890}; と等価

std::ranges:size()を使えば、生配列のサイズも取得できる

int array[100];
std::cout << std::ranges::size(array); // 100

畳み込み式で可変引数

#include <iostream>
#include <string>

using namespace std::literals;

template <typename ... T>
auto add(const T& ... param){
    return (param + ...);
}

int main() {
    auto s = "abc"s;
    std::cout << add(1,2,3) << '\n';            // => 6
    std::cout << add(1.1, 2.2, 3.3) << '\n';    // => 6.6
    std::cout << add(1.1, 2.2, 3) << '\n';      // -> 6.4
    std::cout << add("abc"s, "def"s, "xyz"s) << '\n'; // -> "abcdefxyz"
}