C++ Logo

std-proposals

Advanced search

Re: Initial Idea of Indirect If Statement

From: Jorg Brown <jorg.brown_at_[hidden]>
Date: Sun, 27 Oct 2019 01:04:32 -0700
You wrote that this one line:

    if (DECL : EXPR) X else Y;

is equivalent to these 9 lines:

    {
        auto&& __c = EXPR;
        if (__c) {
            DECL = *__c;
            X;
        } else {
            Y; // noteworthy: DECL is not in scope here
        }
    }

But with the advent of C++11, this is already much much simpler, since the
__c assignment can be folded into the if.

Also, it's a bit misleading to combine everything into one line, for
comparison purposes. And the capitalization makes me think of macros.

I would write it this way. This one line:

  if (type_goes_here decl : expr) X(decl) else Y();

is equivalent to this line:

  if (type_goes_here decl = expr) X(*decl) else Y();

with the exception that decl is not in scope for Y() clause, when this new
form of if is used.

I found your std::get_if use case compelling... but for fun I searched
Google's internal C++ for uses and found 4 already. One use was:

    const PacketVariant packet = ...expr...;
    if (auto packet_ptr = std::get_if<PacketPtr>(&packet)) {
      ScheduleSendPacket(*packet_ptr);
    } else if (auto packet_ptr = std::get_if<InjectablePacketPtr>(&packet))
{
      InjectPacket(*packet_ptr);
    }

As you can see, the fact that the first packet_ptr was still in scope,
didn't prevent us from defining a second packet_ptr with a different type.
And I think that allowing them both to have the same name would have been
the primary benefit of the second packet_ptr not being in scope.

So, sorry, I don't find the extra implicit * worthy of a new language
syntax.

-- Jorg



On Sat, Oct 26, 2019 at 9:15 AM Andrew Tomazos via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> We propose a new variant of the if statement that fuses a condition
> declaration with an indirection in the true branch. We call it an
> 'indirect if statement'.
>
> An indirect if statement of the form:
>
> if (DECL : EXPR) X else Y;
>
> is equivalent to:
>
> {
> auto&& __c = EXPR;
> if (__c) {
> DECL = *__c;
> X;
> } else {
> Y; // noteworthy: DECL is not in scope here
> }
> }
>
> So for example:
>
> int* get();
>
> int main() {
> if (int x : get())
> return x;
> else
> return EXIT_FAILURE;
> }
>
> void f(std::variant<A,B,C> V) {
> if (auto x : std::get_if<A>(V)) {
> /*...*/
> } else if (auto x : std::get_if<B>(V)) {
> /*...*/
> } else if (auto x : std::get_if<C>(V)) {
> /*...*/
> }
> }
>
> template<typename D, typename B>
> D* derived_if(B& b) {
> return dynamic_cast<D*>(&b);
> }
>
> void g(Animal& a) {
> if (auto& dog : derived_if<Dog>(a)) {
> /* ... */
> } else if (auto& cat : derived_if<Cat>(a)) {
> /* ... */
> } else if (auto& pig : derived_if<Pig>(a)) {
> /* ... */
> }
> }
>
> T* ptr;
> std::optional<T> opt;
> std::shared_ptr<T> sptr;
> std::unique_ptr<T> uptr;
>
> int main() {
> if (T x : ptr)
> /*...*/;
>
> if (T x : opt)
> /*...*/;
>
> if (T x : sptr)
> /*...*/;
>
> if (T x : uptr)
> /*...*/
> }
>
> The motivation should be self-evident enough from the examples for this
> first note.
>
> Initial thoughts appreciated.
> -Andrew.
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>

Received on 2019-10-27 03:07:01