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;
stringstream tokenStream(s);
# note that: "123.".split('.') => {"123"} not {"123", ""}
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;