最終更新日時(UTC):
が更新

履歴 編集

function template
<ostream>

std::operator<< (非メンバ関数)

namespace std {
  // 文字の書式化出力
  template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, CharT c);                    // (1)
  template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, char c);                     // (2)
  template<class Traits>
  basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os, char c);                       // (3)
  template<class Traits>
  basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os, unsigned char c);              // (4)
  template<class Traits>
  basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os, signed char c);                // (5)
  // The following deleted overloads prevent formatting character values as numeric values.
  template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, wchar_t) = delete;                // (6) C++20から
  template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char8_t) = delete;                // (7) C++20から
  template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char16_t) = delete;               // (8) C++20から
  template<class traits>
  basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, char32_t) = delete;               // (9) C++20から
  template<class traits>
  basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, char8_t) = delete;          // (10) C++20から
  template<class traits>
  basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, char16_t) = delete;         // (11) C++20から
  template<class traits>
  basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, char32_t) = delete;         // (12) C++20から

  // 文字列の書式化出力
  template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, const CharT* s);             // (13)
  template<class CharT, class Traits>
  basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>& os, const char* s);              // (14)
  template<class Traits>
  basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os, const char* s);                // (15)
  template<class Traits>
  basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os, const unsigned char* s);       // (16)
  template<class Traits>
  basic_ostream<char, Traits>& operator<<(basic_ostream<char, Traits>& os, const signed char* s);         // (17)
  // The following deleted overloads prevent formatting strings as pointer values.
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const wchar_t*) = delete;       // (18) C++20から
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char8_t*) = delete;       // (19) C++20から
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char16_t*) = delete;      // (20) C++20から
  template<class traits>
    basic_ostream<char, traits>& operator<<(basic_ostream<char, traits>&, const char32_t*) = delete;      // (21) C++20から
  template<class traits>
    basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, const char8_t*) = delete; // (22) C++20から
  template<class traits>
    basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, const char16_t*) = delete;// (23) C++20から
  template<class traits>
    basic_ostream<wchar_t, traits>& operator<<(basic_ostream<wchar_t, traits>&, const char32_t*) = delete;// (24) C++20から

  // 右辺値参照ストリームへの出力 (C++11)
  template<class CharT, class Traits, class T>
  basic_ostream<CharT, Traits>& operator<<(basic_ostream<CharT, Traits>&& os, const T& x);                // (25) C++11 から
}

概要

ストリームへの出力を行う。

  • 文字に対するオーバーロードは、書式化出力関数である。
  • 文字列に対するオーバーロードは、書式化出力関数である。

効果

(1)~(5) 文字の書式化出力

文字 c を出力ストリーム os に出力する。この際、os に設定されている幅、埋め文字、および、整列方向に従う。
なお、(2) の形式(os の文字型(char_type)が char 以外で cchar )の時は、c を直接出力するのではなく、os.widen(c) を出力する。
出力後、幅指定は 0 にリセットされる。

(6)~(12) 文字の書式化出力 (C++20)

これらの関数は削除されている

(13)~(17) 文字列の書式化出力

ヌル終端文字列 s を出力ストリーム os に出力する。この際、os に設定されている幅、埋め文字、および、整列方向に従う。
出力する文字列の長さは以下で求める。

  • (13) と (15) の形式:Traits::length(s)
  • (14) の形式:std::char_traits<char>::length(s)
  • (16) と (17) の形式:Traits::length(reinterpret_cast<const char*>(s))

なお、(14) の形式(os の文字型(char_type)が char 以外で sconst char*)の時は、s の各文字 c を直接出力するのではなく、os.widen(c) を出力する。
出力後、幅指定は 0 にリセットされる。

(18)~(24) 文字列の書式化出力 (C++20)

これらの関数は削除されている

(25) 右辺値参照ストリームへの出力 (C++11)

os << xを実行する。
このオーバーロードは、一時オブジェクトなどに対して<<演算子を利用可能にするためのものである。

戻り値

os

備考

  • (25) の形式は C++11 から追加されたが、より使いやすくするための変更が提案されている。
    LWG1203. More useful rvalue stream insertion
  • (3)、および、(15) の形式は、オーバーロード解決時の曖昧さ解消のために存在する。
    (これらが存在しないと、CharTchar 型の場合に、(1) と (2)、あるいは (13) と (14) が同じ優先順位となりオーバーロード解決に失敗してしまう)

(1)、(2)、(13)、(14) の例

#include <iostream>
#include <iomanip>

int main()
{
  std::wcout << std::left << std::setfill(L'+');

  std::wcout << std::setw(10) << L'C' << std::endl;
  std::wcout << std::setw(10) << 'C' << std::endl;

  std::wcout << std::setw(10) << L"cpprefjp" << std::endl;
  std::wcout << std::setw(10) << "cpprefjp" << std::endl;
}

出力

C+++++++++
C+++++++++
cpprefjp++
cpprefjp++

(3)~(5)、(15)~(17) の例

#include <iostream>
#include <iomanip>

int main()
{
  std::cout << std::left << std::setfill('+');

  std::cout << std::setw(10) << 'C' << std::endl;
  std::cout << std::setw(10) << static_cast<signed char>('C') << std::endl;
  std::cout << std::setw(10) << static_cast<unsigned char>('C') << std::endl;

  std::cout << std::setw(10) << "cpprefjp" << std::endl;
  std::cout << std::setw(10) << reinterpret_cast<const signed char*>("cpprefjp") << std::endl;
  std::cout << std::setw(10) << reinterpret_cast<const unsigned char*>("cpprefjp") << std::endl;
}

出力

C+++++++++
C+++++++++
C+++++++++
cpprefjp++
cpprefjp++
cpprefjp++

(25) の例

#include <fstream>
#include <string>
#include <iostream>

int main()
{
  std::ofstream("test.txt") << "cpprefjp" << std::endl;

  std::string s;
  std::ifstream ifs("test.txt");
  ifs >> s;
  std::cout << s << std::endl;
}

出力

cpprefjp

なお、この例は C++03 でもコンパイル・実行可能だが、その場合は出力に謎の 16 進数が出力される。
これは、C++03 では "cpprefjp" の出力の際に operator<<(basic_ostream<char, Traits>&, const char*) ではなく basic_ostream<char, Traits>::operator<<(const void*) が呼び出されるためである。
operator<<(basic_ostream<char, Traits>&, const char*) は左辺に const ではない参照を必要とするため ofstream の一時オブジェクトを受け取れないが、basic_ostream<char, Traits>::operator<<(const void*) はメンバ関数であるため ofstream の一時オブジェクトに対しても呼び出す事が可能)

実装例

TBD

C++20で追加されたdelete指定オーバーロードについて

char8_t型の追加に伴って、次に示すようなコードに破壊的変更が生じてしまった。

#include <iostream>
int main()
{
    std::cout << u8'x';    // C++17までは x と表示された。C++20では120と表示される
    std::cout << u8"text"; // C++20までは text と表示された。C++20では文字列先頭へのポインタが表示される
}

これはchar8_t/char16_t/char32_tに対するostreamのoperator<<が提供されないため、他のオーバーロードが選ばれるためにこのような直感に反する挙動が発生する。

そこで(6)~(12)、(18)~(24)のようにdelete指定されたoperator<<を追加することで不適格にし、このような直感的ではない挙動を避ける。

機能テストマクロ__cpp_lib_char8_tで、値は201907

バージョン

言語

  • C++98
  • C++11: ストリームへの右辺値参照を実引数として受け取るものが追加された
  • C++20: char8_t等への対応の一環としてdelete指定されたoverloadが追加された

関連項目

このほかの<<演算子関数

出力対象の型

C++20での変更関連

参照

P1423R3: char8_t backward compatibility remediation