LoginSignup
0
0

More than 1 year has passed since last update.

【C++20】sリテラルについて

Last updated at Posted at 2021-10-11

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 は文字列となる。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0