Skip to content

SpscQueue: Consider std::expected<T, E> for pop() return type #60

Description

@jsrivaya

Summary

Explore using std::expected<T, E> (C++23) as the return type for pop() to provide richer error information and a more ergonomic API.

Motivation

The current pop(T& value) API uses an output parameter and returns bool. While simple and zero-overhead, it gives no information about why the operation failed and requires an output parameter rather than a natural return value.

std::expected enables:

// Current
T value;
if (!queue.pop(value)) { /* handle empty */ }

// With std::expected
auto result = queue.pop();
if (result) {
    process(*result);
} else if (result.error() == QueueError::Empty) {
    // handle empty
}

Proposed API

enum class QueueError { Empty, Full };

// pop returns value or error
[[nodiscard]] std::expected<T, QueueError> pop();

// push could also return error info
[[nodiscard]] std::expected<void, QueueError> push(const T& value);
[[nodiscard]] std::expected<void, QueueError> push(T&& value);

Monadic chaining (C++23)

queue.pop()
    .transform([](T v) { return process(v); })
    .or_else([](QueueError e) {
        log("queue empty");
        return std::expected<Result, QueueError>{};
    });

Trade-offs

Aspect bool + out-param std::expected
Overhead Zero Zero (same layout)
Error info None Full error type
Ergonomics Requires out-param Natural return value
C++ version C++11 C++23
Familiarity High Lower (newer)

Considerations

  • Zero runtime overhead — std::expected is as cheap as std::optional for the success path
  • Backwards-incompatible API change — would require a major version bump
  • Could offer both APIs: keep pop(T&) and add try_pop() returning std::expected
  • Useful if error types expand (e.g. Closed when a close() method is added)

References

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions