C/C++ Arena

Step 7 of 7

Challenge: a move-aware log

One last tool. std::exchange(obj, new_value) from <utility> sets obj to new_value and returns the old value, moving where it can. It's the tidy way to "take" something and leave a reset value behind, in one line.

#include <iostream>
#include <string>
#include <utility>
#include <vector>

class Cart {
public:
    void add(std::string item) {
        if (item.empty()) return;
        items_.push_back(std::move(item));      // sink: move into storage
    }
    std::vector<std::string> checkout() {
        return std::exchange(items_, {});       // hand over, leave an empty cart
    }
    int size() const { return (int)items_.size(); }

private:
    std::vector<std::string> items_;
};

int main() {
    Cart cart;
    cart.add("milk");
    cart.add("");
    cart.add("bread");
    std::cout << cart.size() << " in cart\n";

    std::vector<std::string> bought = cart.checkout();
    std::cout << bought.size() << " bought, " << cart.size() << " left\n";

    int ticket = 7;
    int old = std::exchange(ticket, ticket + 1);
    std::cout << old << " then " << ticket << "\n";
}
2 in cart
2 bought, 0 left
7 then 8

How it works

Putting it together for your Log

Your Log is the same shape as Cart: a sink add that skips empty lines, a size, and a flush that hands over all the lines and leaves the log empty.

Your turn: write class Log:

Previous: Sink parameters and emplace_back