#include #include #include #include #include template class Stack { public: template Stack(Args&&... args) : data { std::forward(args)... } { } Stack& operator<<(T const& value) { data.push_back(value); return *this; } Stack& operator>>(T& value) { value = data.back(); data.pop_back(); return *this; } bool operator==(T const& rhs) const { return data.back() == rhs; } bool is_empty() const { return data.empty(); } private: friend std::ostream& operator<<(std::ostream& os, Stack const& stack) { for (std::size_t i { stack.data.size() }; i > 0; --i) { os << stack.data[i - 1] << " "; } return os; } std::vector data { }; }; 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 ); 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.is_empty()) { int x; st >> x; assert(x == i); ++i; } } { Stack st { "f", "e", "d" }; assert( st == "d" ); st << "c" << "b" << "a"; assert( st == "a" ); std::ostringstream oss { }; oss << st; assert( oss.str() == "a b c d e f "); // popping into a, b and c as a chained operator call. std::string a, b, c; st >> a >> b >> c; assert( a == "a" ); assert( b == "b" ); assert( c == "c" ); } }