On Fri, Jul 22, 2022 at 2:37 PM Thiago Macieira via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
On Friday, 22 July 2022 11:11:21 PDT Hyman Rosen wrote:
> On Fri, Jul 22, 2022 at 11:24 AM Thiago Macieira wrote:
> > Hence the rule: NEVER use a std::pair. There are no exceptions, zero, nada, nil.
>
> If we cannot trust the language standardization process to produce a usable
> library type that just represents a pair of things, why would we trust it
> to produce usable library types for concurrent programming, or for anything
> else, for that matter?  Isn't this a sign that something is dreadfully
> wrong?

No. The problem is not with std::pair. There's nothing wrong with the class as
standardised (which was C++98, so it's dated) [...] the problem with std::pair is that there are ZERO valid use-cases
calling for its use where there isn't a better solution available. Examples of
better solutions:
std::to_chars_result - https://en.cppreference.com/w/cpp/utility/to_chars
std::from_chars_result - https://en.cppreference.com/w/cpp/utility/from_chars

To put it another way (or maybe just to say something else ;)) — This is Yet Another of those common cases where there's a library solution and a core-language solution, and the core-language solution is strictly better pretty much all of the time. (Personally I won't say "100% always," but almost always, for sure.)
Other examples include:
    std::for_each(v.begin(), v.end(), do_a_thing);  // library
vs.
    for (auto&& elt : v) do_a_thing(elt);  // core-language
and
    foo(std::decay_t<decltype((expr))>(expr));  // library
vs.
    foo(auto(expr));  // core-language (C++23)
and also C++20 coroutines, but I'm not qualified to write that example. ;)

In this case, the two solutions are
    std::pair<Sema, Sema> mygate;  // library
    mygate.first.acquire();
vs.
    struct { Sema isOpen; Sema isClosed; } mygate;  // core-language
    mygate.isOpen.acquire();

(Also notice that elsethread we've already gotten a better answer, using a single `std::atomic<bool>`, which moots the whole question of what to use instead of a pair, because now we've only got a single thing anyway.)
(Also also, I'll agree with everyone who's said that "gate" is a completely idiosyncratic name — I've never heard of "gate" anywhere else, and with no explanation/documentation I might incorrectly interpret it as a synonym for "std::barrier", which would be wrong. Whereas "semaphore" is a very well-established primitive; it's taught in schools and has a Wikipedia article and everything. "Gate", AFAICT, does not.)

my $.02,
Arthur