std::string_literals::sリテラル
sリテラルについて調べたので記録を残す。
sリテラルとは
文字列リテラルを受け取り、各文字型のbasic_string
を構築する機能を持つオペレーター(operator)のことである。
basic_stringとは
basic_string
クラスとは、あらゆる文字型を使用できるクラスである。
ヘッダ
ヘッダは下記のように<string>
をインクルードする必要がある。
#include <string>
名前空間
名前空間の構造は以下のようになっている。
namespace std {
inline namespace literals {
inline namespace string_literals {
~~定義~~
}
}
}
usingディレクティブ(using directive)
sリテラルを使用するには、下記のようにusingディレクティブを用いてnamespaceの検索範囲を拡張させる必要がある。
あるいは次項に記載するusing宣言でoperatorを指定のスコープに取り込む必要があります。
ちなみにinline namepsaceの部分は省略することができます。
using namespace std::literals::string_literals;
using namespace std::literals;
using namespace std::string_literals;
using namespace std; // この書き方も可能だが、取り込まれる名前空間が膨大すぎるため推奨されない
using宣言
using宣言でoperatorだけをスコープに取り込みたい場合は下記のように記載する。
もちろんinline namepsaceの部分は省略することができます。
using std::literals::string_literals::operator""s;
using std::literals::operator""s;
using std::string_literals::operator""s;
using std::operator""s;
sリテラル実践
実際にsリテラルを使用してみる。
ついでにsリテラルを使用する場合と、使用しない場合を比較する。
プログラム内容:sリテラル使用時と不使用時、それぞれのサイズと中身、および型の比較を行う。
source : sliteral.cpp
#include <iostream>
#include <string>
#include <typeinfo>
#include <cxxabi.h>
using std::literals::string_literals::operator""s; // enables s-suffix for std::string literals
char* demangle(const char *demangle) {
int status;
return abi::__cxa_demangle(demangle, 0, 0, &status);
}
int main()
{
std::string s1 = "abc\0\0def";
std::string s2 = "abc\0\0def"s;
std::cout << "s1: " << s1.size() << " \"" << s1 << "\"\n";
std::cout << "s2: " << s2.size() << " \"" << s2 << "\"\n";
std::cout << std::endl;
std::cout << demangle(typeid("abc\0\0def").name()) << std::endl;
std::cout << demangle(typeid("abc\0\0def"s).name()) << std::endl;
}
result
$ g++ -std=c++20 -Wall -pedantic-errors -o program ./sliteral.cpp
$ ./program.exe
s1: 3 "abc"
s2: 8 "abcdef"
char [9]
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >
実行結果まとめ
sリテラルを使用していない場合は、char型の配列で、null文字までを一塊とした文字列のようだ。これはC言語と変わらない。
一方でsリテラルを使用すると、basic_stringオブジェクトとなっている。
sリテラル | ターゲット | size() | cout |
---|---|---|---|
不使用 | std::string s1 = "abc\0\0def" |
3 | "abc" |
使用 | std::string s2 = "abc\0\0def"s |
8 | "abcdef" |
sリテラル | ターゲット | 型 |
---|---|---|
不使用 | "abc\0\0def" |
char [9] |
使用 | "abc\0\0def"s |
std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > |
メモ
std::chrono_literals::sリテラル という算術リテラルもある。
つまり10s
は10秒ですが、 "10"s
は文字列となる。