C++ Language

FileReader

class FileReader {
private:
    fstream file;
public:
    FileReader(string const & file_dir) {
        file = fstream(file_dir);
        if (!file.is_open()) {
            throw runtime_error("Can not open file");
        }
    }
    bool get_line(string & next_line) {
        return !!getline(file, next_line);
    }
};

Split

vector<string> split(string const & s, char delimiter)
{
   vector<std::string> tokens;
   string token;
   istringstream tokenStream(s);
   while (getline(tokenStream, token, delimiter))
   {
      tokens.push_back(token);
   }
   return tokens;
}

Explicit vs Implicit Constructor

struct A
{
    A(int) { }      // converting constructor
    A(int, int) { } // converting constructor (C++11)
    operator bool() const { return true; }
};
 
struct B
{
    explicit B(int) { }
    explicit B(int, int) { }
    explicit operator bool() const { return true; }
};
 
int main()
{
    A a1 = 1;      // OK: copy-initialization selects A::A(int)
    A a2(2);       // OK: direct-initialization selects A::A(int)
    A a3 {4, 5};   // OK: direct-list-initialization selects A::A(int, int)
    A a4 = {4, 5}; // OK: copy-list-initialization selects A::A(int, int)
    A a5 = (A)1;   // OK: explicit cast performs static_cast
    if (a1) ;      // OK: A::operator bool()
    bool na1 = a1; // OK: copy-initialization selects A::operator bool()
    bool na2 = static_cast<bool>(a1); // OK: static_cast performs direct-initialization
 
//  B b1 = 1;      // error: copy-initialization does not consider B::B(int)
    B b2(2);       // OK: direct-initialization selects B::B(int)
    B b3 {4, 5};   // OK: direct-list-initialization selects B::B(int, int)
//  B b4 = {4, 5}; // error: copy-list-initialization does not consider B::B(int,int)
    B b5 = (B)1;   // OK: explicit cast performs static_cast
    if (b2) ;      // OK: B::operator bool()
//  bool nb1 = b2; // error: copy-initialization does not consider B::operator bool()
    bool nb2 = static_cast<bool>(b2); // OK: static_cast performs direct-initialization
}

Custom Hash

class Solution {
public:
    class Position {
    public:
        int s_x, s_y;
        int b_x, b_y;
        Position(int s_x_, int s_y_, int b_x_, int b_y_) : s_x(s_x_), s_y(s_y_), b_x(b_x_), b_y(b_y_) {}
        // must override operator == to handle hash conflict
        bool operator == (Position const &another) const {
            return s_x == another.s_x && s_y == another.s_y && b_x == another.b_x && b_y == another.b_y;
        }
    };
    
    class PositionHash {
    public:
        // lazy solution, use built-in std::hash<T>()
        size_t operator() (Position const &p) const {
            return hash<string>()(to_string(p.s_x) + "," + to_string(p.s_y) + "," + to_string(p.b_x) + "," + to_string(p.b_y));
        }
    };

    class PeopleHash {
    public:
        size_t operator() (Position const &p) const {
            return (p.s_x + 1) * 100 + p.s_y;
        }
    };

    class BoxHash {
    public:
        size_t operator() (Position const &p) const {
            return (p.b_x + 1) * 100 + p.b_y;
        }
    };

    void example() {
        unordered_set<Position, BoxHash> visited;
    }
};

Unique Pointers to Shared Pointers

//In short, you can easily and efficiently convert a std::unique_ptr to std::shared_ptr but you cannot convert std::shared_ptr to std::unique_ptr.

std::unique_ptr<std::string> unique = std::make_unique<std::string>("test");
std::shared_ptr<std::string> shared = std::move(unique);
// or
std::shared_ptr<std::string> shared = std::make_unique<std::string>("test");

String View

string text_ = "Hello World";
string_view text(text_);
cout << text.substr(0, 5) << endl; // substr is O(1)
return 0;