Skip to content

private variants #1

@fbenkstein

Description

@fbenkstein

After the talk I suggested a downside to variants being complete, so extending a variant later (e.g. in the case of events). I came up with a possible solution:

namespace nonexhaustive_variant {
namespace detail {
template <class... T>
class nonexhaustive_variant {
  struct P {};

 public:
  using type = std::variant<T..., P>;
};
}  // namespace detail

template <class... T>
using nonexhaustive_variant = typename detail::nonexhaustive_variant<T...>::type;
}  // namespace nonexhaustive_variant

using nonexhaustive_variant forces users of match to always provide a generic matcher:

struct A {};
struct B {};

using V = nonexhaustive_variant::nonexhaustive_variant<A, B>;

void foo(const V& v) {
  match(v,  //
        [](const A&) { std::cout << "A" << std::endl; },
        [](const B&) { std::cout << "B" << std::endl; },
        [](const auto&) { std::cout << "???" << std::endl; });
}

Since the type P is private since it cannot be matched explicitely. This allows extending V in an interface without breaking all users of a library.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions