#include #include #include #include template class Stack { public: Stack(std::initializer_list list) : values { list.begin(), list.end() } { } explicit operator bool() const { return !values.empty(); } operator T() const { return values.back(); } Stack& operator<<(T const& value) { values.push_back(value); return *this; } Stack& operator>>(T& value) { value = values.back(); values.pop_back(); return *this; } std::string to_string() const { std::ostringstream oss { }; for (std::size_t i { values.size() }; i > 0; --i) { oss << values[i - 1] << " "; } return oss.str(); } private: std::vector values {}; }; template std::ostream& operator<<(std::ostream& os, Stack const& stack) { os << stack.to_string(); return os; } int main() { { Stack st { 6, 5, 4 }; // 4 should be at the top of the stack assert( st == 4 ); // pushing 3, 2 and 1 to the stack st << 3 << 2 << 1; // now 1 should be at the top assert( st == 1 ); // stack must be convertible to bool assert( st ); std::ostringstream oss { }; oss << st; assert( oss.str() == "1 2 3 4 5 6 "); // popping into a, b and c as a chained operator call. int a, b, c; st >> a >> b >> c; assert( a == 1 ); assert( b == 2 ); assert( c == 3 ); // pop the values one by one int i { 4 }; while (st) { int x; st >> x; assert(x == i); ++i; } // now the list should be empty assert( !st ); } }