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
>
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