C++学习——自定义format

在学习C++的时候总是习惯于写一些简单的demo来测试这些新方法的使用。今天我就基于之前写的关于运算符重载的demo--复数类的实现进行重写。新的demo中我实现了使用std::format输出自定义类型。
我这里参考的是文章C++20 使用std::format输出自定义类型 - 知乎 (zhihu.com)

#include <format>
#include <iostream>
#include <sstream>
#include <string>

using std::cin;
using std::cout;
using std::format;
using std::istream;
using std::ostream;

template <typename T> class complex {
public:
  complex(T real = 0.0, T imag = 0.0) : m_real(real), m_imag(imag){};

public:
  //重载加法运算符
  friend complex operator+(const complex &A, const complex &B) {
    return complex(A.m_real + B.m_real, A.m_imag + B.m_imag);
  }

  //重载减法运算符
  friend complex operator-(const complex &A, const complex &B) {
    return complex(A.m_real - B.m_real, A.m_imag - B.m_imag);
  }

  //重载乘法运算符
  friend complex operator*(const complex &A, const complex &B) {
    return complex(A.m_real * B.m_real - A.m_imag * B.m_imag,
                   A.m_imag * B.m_real + A.m_real * B.m_imag);
  }

  //重载除法运算符
  friend complex operator/(const complex &A, const complex &B) {
    double square = A.m_real * A.m_real + A.m_imag * A.m_imag;
    return complex((A.m_real * B.m_real + A.m_imag * B.m_imag) / square,
                   (A.m_imag * B.m_real - A.m_real * B.m_imag) / square);
  }

  //重载输入运算符
  friend istream &operator>>(istream &in, complex &A) {
    in >> A.m_real >> A.m_imag;
    return in;
  }

  //重载输出运算符
  friend ostream &operator<<(ostream &out, complex &A) {
    out << A.m_real << " + " << A.m_imag << " i ";
    return out;
  }
  friend class std::formatter<complex, char>;

private:
  T m_real; //实部
  T m_imag; //虚部
};

template <typename T>
class std::formatter<complex<T>, char>
    : public std::_Formatter_base<complex<T>, char,
                                  std::_Basic_format_arg_type::_Custom_type>
// _Basic_format_arg_type是个枚举类,_Custom_type用于说明是自定义类型
{
public:
  // format用于输出格式化的内容,比较简单输出格式和cout输出格式类似
  template <class _FormatContext>
  auto format(const complex<T> &val, _FormatContext &format_ctx) noexcept {
    std::ostringstream out_sstream;
    val.m_imag == 0 ? out_sstream << val.m_real
                    : out_sstream << val.m_real << (val.m_imag > 0 ? "+" : "")
                                  << val.m_imag << "i";
    return formatter<string, char>().format(out_sstream.str(), format_ctx);
  }
};

int main() {
  complex<double> c1, c2;
  cin >> c1 >> c2;
  cout << format("{} + {} = {}\n", c1, c2, c1 + c2);

  cout << format("{} - {} = {}\n", c1, c2, c1 - c2);

  cout << format("{} * {} = {}\n", c1, c2, c1 * c2);

  cout << format("{} / {} = {}\n", c1, c2, c1 / c2);

  return 0;
}

 

posted @ 2022-03-08 15:29  丸子球球  阅读(617)  评论(0编辑  收藏  举报