C++クイズ:How many operator<< overloads?
#include <iostream>
int main()
{
std::cout << "<<演算子オーバーロードは全部で何種類?";
}
<<
演算子オーバーロードについて。C++のストリーム出力で活躍中
<<
演算子のオーバーロードってご存じですか?C++標準ライブラリのストリーム出力に使われる演算子ですよね!
文字列以外にも整数(int
など)や浮動小数点数(float
など)のストリーム出力用に、それぞれ演算子オーバーロードが提供されているようです。C++標準ライブラリ全体では何種類のオーバーロードが存在する のでしょうか?
せいぜい 10 種類くらい?もっとたくさん 50 種類くらいでしょうか?さっそくC++バージョン別に調べてみました!!
<<
演算子オーバーロードの種類は?どのヘッダで定義される!?
C++03
C++03標準ライブラリでは、28 種類のストリーム出力operator<<
オーバーロードが提供されていました。
// <ostream>
template<class charT, class traits = char_traits<charT> >
class basic_ostream {
basic_ostream<charT,traits>& operator<<(bool n);
basic_ostream<charT,traits>& operator<<(short n);
basic_ostream<charT,traits>& operator<<(unsigned short n);
basic_ostream<charT,traits>& operator<<(int n);
basic_ostream<charT,traits>& operator<<(unsigned int n);
basic_ostream<charT,traits>& operator<<(long n);
basic_ostream<charT,traits>& operator<<(unsigned long n);
basic_ostream<charT,traits>& operator<<(float f);
basic_ostream<charT,traits>& operator<<(double f);
basic_ostream<charT,traits>& operator<<(long double f);
basic_ostream<charT,traits>& operator<<(const void* p);
basic_ostream<charT,traits>&
operator<<(basic_streambuf<char_type,traits>* sb);
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& (*pf)(basic_ostream<charT,traits>&));
basic_ostream<charT,traits>&
operator<<(basic_ios<charT,traits>& (*pf)(basic_ios<charT,traits>&));
basic_ostream<charT,traits>&
operator<<(ios_base& (*pf)(ios_base&));
};
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>&, charT);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>&, char);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, char);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, signed char);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, unsigned char);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>&, const charT*);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>&, const char*);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const char*);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const signed char*);
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const unsigned char*);
// <string>
template<class charT, class traits, class Allocator>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const basic_string<charT,traits,Allocator>& str);
// <complex>
template<class T, class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>&, const complex<T>&);
// <bitset>
template<class charT, class traits, size_t N>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const bitset<N>& x);
おまけ:本来の「左ビットシフト」の意味でも 4 種類が提供されています。
// <bitset>
bitset<N> operator<<(size_t pos) const;
// <valarray>
valarray<T> operator<<(const valarray<T>&, const valarray<T>&);
valarray<T> operator<<(const valarray<T>&, const T&);
valarray<T> operator<<(const T&, const valarray<T>&);
C++11/14
C++11標準ライブラリでは、33 種類のストリーム出力operator<<
オーバーロードが追加されました。累計だと 61 種類になります!
ちなみに、C++14標準ライブラリでの追加は行われていないようです。
// <ostream>
template<class charT, class traits = char_traits<charT> >
class basic_ostream {
basic_ostream<charT,traits>& operator<<(long long value);
basic_ostream<charT,traits>& operator<<(unsigned long long value);
};
template<class charT, class traits, class T>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>&& os, const T& x);
// <system_error>
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const error_code& ec);
// <memory>
template<class charT, class traits, class Y>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const shared_ptr<Y>& p);
// <regex>
template<class charT, class traits, class BiIter>
basic_ostream<charT,traits>&
operator<<(basic_ostream<ccharT,traits>& os, const sub_match<BiIter>& m);
// <thread>
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& out, thread::id id);
// <random>
// Random number engine requirement
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const linear_congruential_engine& e);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const mersenne_twister_engine& e);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const subtract_with_carry_engine& e);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const discard_block_engine& e);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const independent_bits_engine& e);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const shuffle_order_engine& e);
// Random number distribution requirement
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const uniform_int_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const uniform_real_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const bernoulli_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const binomial_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const negative_binomial_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const geometric_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const poisson_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const exponential_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const gamma_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const weibull_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const extreme_value_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const normal_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const lognormal_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const chi_squared_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const cauchy_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const fisher_f_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const student_t_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const discrete_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const piecewise_constant_distribution& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const piecewise_linear_distribution& d);
C++17
C++17標準ライブラリでは、3 種類のストリーム出力operator<<
オーバーロードが追加されました。累計だと 64 種類になります!
// <ostream>
template<class charT, class traits = char_traits<charT> >
class basic_ostream {
basic_ostream<charT,traits>& operator<<(nullptr_t);
};
// <string_view>
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, basic_string_view<charT,traits> str);
// <filesystem>
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const path& p);
おまけ2:本来の「左ビットシフト」の意味でも 1 種類が追加され、こちらは 5 種類目となります。
// <cstddef>
constexpr byte operator<<(byte b, IntType shift) noexcept;
C++20
最新のC++20標準ライブラリでは、42 種類のストリーム出力operator<<
オーバーロードが追加されました。とうとう大台に乗り 106 種類です!!
// <memory>
template<class charT, class traits, class Y, class D>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const unique_ptr<Y,D>& p);
// <chrono>
template<class charT, class traits, class Rep, class Period>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const duration<Rep,Period>& d);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const sys_time<Duration>& tp);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const sys_days& dp);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const utc_time<Duration>& t);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const tai_time<Duration>& t);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const gps_time<Duration>& t);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const file_time<Duration>& tp);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const local_time<Duration>& tp);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const day& d);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const month& m);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const year& y);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const weekday& wd);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const weekday_indexed& wdi);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const weekday_last& wdl);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const month_day& md);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const month_day_last& mdl);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const month_weekday& mwd);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const month_weekday_last& mwdl);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const year_month& ym);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const year_month_day& ymd);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const year_month_day_last& ymdl);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const year_month_weekday& ymwdi);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const year_month_weekday_last& ymwdl);
template<class charT, class traits, class Duration>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const hh_mm_ss<Duration>& hms);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const sys_info& si);
template<class charT, class traits>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const local_info& li);
template<class charT, class traits, class Duration, class TimeZonePtr>
basic_ostream<charT,traits>&
operator<<(basic_ostream<charT,traits>& os, const zoned_time<Duration,TimeZonePtr>& t);
// <ostream>
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, wchar_t) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, char8_t) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, char16_t) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, char32_t) = delete;
template<class traits>
basic_ostream<wchar_t,traits>&
operator<<(basic_ostream<wchar_t,traits>&, char8_t) = delete;
template<class traits>
basic_ostream<wchar_t,traits>&
operator<<(basic_ostream<wchar_t,traits>&, char16_t) = delete;
template<class traits>
basic_ostream<wchar_t,traits>&
operator<<(basic_ostream<wchar_t,traits>&, char32_t) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const wchar_t*) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const char8_t*) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const char16_t*) = delete;
template<class traits>
basic_ostream<char,traits>&
operator<<(basic_ostream<char,traits>&, const char32_t*) = delete;
template<class traits>
basic_ostream<wchar_t,traits>&
operator<<(basic_ostream<wchar_t,traits>&, const char8_t*) = delete;
template<class traits>
basic_ostream<wchar_t,traits>&
operator<<(basic_ostream<wchar_t,traits>&, const char16_t*) = delete;
template<class traits>
basic_ostream<wchar_t,traits>&
operator<<(basic_ostream<wchar_t,traits>&, const char32_t*) = delete;
<<演算子オーバーロードのまとめ
いかがでしたでしょうか?C++20標準ライブラリのストリーム出力operator<<
オーバーロードを数えてみたら 106 種類も提供されるようです!今後もoperator<<
オーバーロードの増加から目が離せませんね!!!
正直、面倒臭すぎてもうやりたくありません。 ⊂⌒~⊃。~。)⊃
Acknowledgements
Discussion