リテラル区切り文字

重箱の隅をつついてみた。

まず、リテラルとして二進数が使えるようになってる。

int i = 0b1111;

さらに、二進数で64ビットとか、浮動小数点数とか表現するのが大変だからか、リテラルの区切り文字が使える。

int i = 0b1111'0000'1010'0101;

シングルクォートじゃなくてアンダーバーにすれば良かったのにとは思うけど、区切り文字があるのは嬉しい。

ただ、数字以外の文字とくっつくと、コンパイルエラーになる。

int i = 0b'1111; // エラー

double d = 1.'23456789; // エラー

うん、まあそうだよね。

ユーザ定義リテラルの定数化

ユーザ定義リテラルをコンパイル時定数として扱う。


#include <iostream>
 
constexpr unsigned long long int operator""_km(unsigned long long int meter) {
    return meter * 1000;
}
 
int main() {
    const int distance = 1_km;
    std::cout << "distance:[" << distance << "]" << std::endl;

    return 0;
}

「constexpr」を付加することで、コンパイル時に評価されるようになる…はずだけど、「Visual Studio Community 2017」では、実行時評価みたい。

8行目にブレイクポイントを置いても、「distance」は評価済みの気配がない。

初めてのユーザ定義リテラル

C++11からおもしろい機能が入ってた。

リテラルのサフィックスをユーザが指定できる。

#include <iostream>

unsigned long long int operator””_km(unsigned long long int meter) {

return meter * 1000;

}

int main() {

int distance = 1_km;
std::cout << “distance:[” << distance << “]” << std::endl;

return 0;

}

演算子のオーバーロードの要領で、「『””』+『なんとか』」を作ると、「なんとか」を初期化で使える。

「なんとか」は、アンダーバーで始めなければならないらしいけど、可読性は上がるね。

main関数は特別扱いの続き

最近のC++では、main関数の再帰呼び出しが禁止されていると聞いたので試してみた。

int main() { main(); }

コンパイルして実行できちゃうよ、Visual Studio Community 2017。

GCCでも試してみた。

→ main関数は再帰で呼べます。

 

~/source/c++>cat tmp.cpp
int main() {
main();
}

~/source/c++>g++ –version
g++ (GCC) 7.2.1 20170829 (Red Hat 7.2.1-1)
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

~/source/c++>g++ -std=c++17 -Wall tmp.cpp
~/source/c++>