C++ Pair 구현하기

Don’t reinvent the wheel; use libraries.

From <The C++ Programming Language> by Bjarne Stroustrup

들어가기에 앞서

앞으로 게시될 일련의 게시물들은 STL을 쓰지 못하는 특정 상황을 위해 STL과 비슷하게 동작하는 container, data structure, algorithm 등을 구현한 것 들입니다.
STL 상의 모든 함수들을 구현하지는 못하였지만(특히 iterator 관련…) 사용하는데 큰 지장은 없을 것 입니다.

STL을 사용할 수 있는 상황이라면 STL을 사용하도록 합시다.
나보다 똑똑한 사람들이 나보다 더 많은 시간을 들여서 작성하고 최적화한 코드입니다.

구현된 STL-like 자료 구조들은 Github Repo에서도 확인 하실 수 있습니다.

혹시나 있을 버그는 댓글 혹은 이메일로 제보해 주시면 수정하도록 하겠습니다.

가장 먼저 구현한 자료구조는 아니지만 가장 간단하여 첫 게시물로 어울릴 것이라 생각한 pair 입니다.
문제 풀이에 활용도가 매우 높으며 header 내에 있습니다.

Documents

FunctionDescription
Pair(const T1& f, const T2& s)initialization constructor
Pair(U1&& f, U2&& s)initialization constructor
Pair(const Pair<U1,U2>& other)copy constructor
Pair(Pair<U1,U2>&& other)move constructor
void swap(Pair& other)swap contents of this with other
make_pair(U1&& x, U2&& y)Constructs a pair object with its first element set to x and its second element set to y.1
assign operator=
compare operator==, !=, <, <=, >, >=

1 : using namespace std; 등을 사용하였을 때 STL의 make_pair와 overloading에서 문제가 발생할 수 있습니다.
이 경우 구현에서 해당 함수를 주석 처리 해주시기 바랍니다.

구현

template <typename T1, typename T2>
class Pair{
public:
  T1 first;
  T2 second;

  constexpr Pair() : first(T1()), second(T2()) {};

  Pair(const T1& f, const T2& s) : first(f), second(s) {};

  template<typename U1, typename U2>
  Pair(U1&& f, U2&& s) : first(std::forward<U1>(f)), second(std::forward<U2>(s)) {};

  template<typename U1, typename U2>
  Pair(const Pair<U1,U2>& other) : first(other.first), second(other.second) {};

  template<typename U1, typename U2>
  Pair(Pair<U1,U2>&& other) : first(std::forward<U1>(other.first)), second(std::forward<U2>(other.second)) {};

  ~Pair() = default;

  void swap(Pair& other) {
    std::swap(first, other.first);
    std::swap(second, other.second);
  }

  Pair& operator=(const Pair& other) {
    first = other.first;
    second = other.second;
    return *this;
  }

  Pair& operator=(Pair&& other) {
    first = std::move(other.first);
    second = std::move(other.second);
    return *this;
  }
  template<typename U1, typename U2>
  Pair& operator=(const Pair<U1, U2>& other) {
    first = other.first;
    second = other.second;
    return *this;
  }

  template<typename U1, typename U2>
  Pair& operator=(Pair<U1, U2>&& other) {
    first = std::forward<T1>(other.first);
    second = std::forward<T2>(other.second);
    return *this;
  }

  inline bool operator==(const Pair& other) const { return (first == other.first && second == other.second); }
  inline bool operator!=(const Pair& other) const { return !(*this == other); }
  inline bool operator< (const Pair& other) const { return (first < other.first || (first == other.first && second < other.second)); }
  inline bool operator<=(const Pair& other) const { return !(other < *this); }
  inline bool operator> (const Pair& other) const { return (other < *this); }
  inline bool operator>=(const Pair& other) const { return !(*this < other); }
};

// comment below function if overloading conflict happens.(using namespace std;)
template <typename U1, typename U2>
inline Pair<U1,U2> make_pair(U1&& x, U2&& y) {
  return Pair<U1,U2> {x, y};
}

© 2020. All rights reserved.