Null coalescing operator

894 views
Skip to first unread message

philippe...@gmail.com

unread,
May 11, 2017, 5:19:31 PM5/11/17
to ISO C++ Standard - Future Proposals
I've decided to dip my toe into the standardization process. As such, I've come up with (what I think is) a small feature I really like. I have to do a lot of programming in [other language] at work, and something I greatly miss when getting back to C++ is the null coalescing operator. It is a quality of life feature that simplifies and compacts patterns of code that are used throughout codebases.

Consider the following conditional operator use case:

Test* get_test() { /*...*/ }

Test* test = (get_test() != nullptr) ? get_test() : new Test();


If `get_test()` has side effects, we may have a problem. We would use the following instead.

Test* test = get_test();
test
= test != nullptr ? test : new Test();


We could instead use a shortcut without side effect, the null coalescing operator ??. 
The left hand side expression is evaluated and compared to nullptr. If it is not nullptr, the evaluation is complete. If it is nullptr, the right hand side expression is evaluated.

Test* test = get_test() ?? new Test();


It can also be a concise way to throw on a null value.

some_pointer ?? throw std::invalid_argument("some_pointer is null.");


These are the most interesting aspects of the feature. I'd like to gather thoughts and comments. Maybe it has already been mentioned in a paper that didn't go through? I'm simply interested in getting the discussion started before writing a paper. If the general consensus is that this feature is desired, maybe you could point me to a committee member that could mentor me?

Thank you,
Philippe

Shahms King

unread,
May 11, 2017, 5:59:04 PM5/11/17
to ISO C++ Standard - Future Proposals
This is typically spelled '?:' and exists as an extension in both Clang and GCC.  I seem to recall that it's been proposed previously and rejected due to "insufficient cause".

"""
A proposal for a null-coalescing conditional operator, a ?: b, which would have been equivalent to a ? a : b. EWG felt the utility wasn’t sufficiently compelling to warrant a language change.
"""
(Although the referenced link is to a paper that has nothing to do with the operator in question).

--Shahms

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/8a34f78a-53ec-48d3-934f-457fd6d949d7%40isocpp.org.

Barry Revzin

unread,
May 11, 2017, 6:03:44 PM5/11/17
to ISO C++ Standard - Future Proposals
"""
(Although the referenced link is to a paper that has nothing to do with the operator in question).

Looks like Botond just swapped some digits. It's 4120, not 4210: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4120.pdf 

Ville Voutilainen

unread,
May 11, 2017, 6:03:46 PM5/11/17
to ISO C++ Standard - Future Proposals
On 12 May 2017 at 00:58, Shahms King <shahm...@gmail.com> wrote:
> This is typically spelled '?:' and exists as an extension in both Clang and
> GCC. I seem to recall that it's been proposed previously and rejected due
> to "insufficient cause".
>
> From
> https://botondballo.wordpress.com/2014/11/23/trip-report-c-standards-meeting-in-urbana-champaign-november-2014/
> """
> A proposal for a null-coalescing conditional operator, a ?: b, which would
> have been equivalent to a ? a : b. EWG felt the utility wasn’t sufficiently
> compelling to warrant a language change.
> """
> (Although the referenced link is to a paper that has nothing to do with the
> operator in question).


It's linking to N4210, whereas the right paper is
http://open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4120.pdf

Philippe Groarke

unread,
May 11, 2017, 6:08:33 PM5/11/17
to std-pr...@isocpp.org
I felt it might have already be proposed, thanks for the quick reply. Back to the drawing board.

Ville Voutilainen

unread,
May 11, 2017, 6:34:39 PM5/11/17
to ISO C++ Standard - Future Proposals
On 12 May 2017 at 01:08, Philippe Groarke <philippe...@gmail.com> wrote:
> I felt it might have already be proposed, thanks for the quick reply. Back
> to the drawing board.

The goal was

Test* test = get_test() ?? new Test();

and the shortest work-around I can concoct quickly is

Test* test = []{Test* ret{get_test()}; return ret ? ret : new Test();}();

Not all that pretty, no.

raffael...@mavensecurities.com

unread,
May 12, 2017, 5:27:19 AM5/12/17
to ISO C++ Standard - Future Proposals
On Thursday, 11 May 2017 23:34:39 UTC+1, Ville Voutilainen wrote:
and the shortest work-around I can concoct quickly is

Test* test = []{Test* ret{get_test()}; return ret ? ret : new Test();}();

Not all that pretty, no.

Well perhaps this is a little prettier?

Test * test = [x=get_test()](){ return x ? x : new Test(); };

And you can just define a template function:

template<typename T, typename F>
T coalesce(T&& x, F&& f)
{ return x ? x : f(); }

Test *test = coalesce(get_test(), [](){ return new Test(); });

dgutson .

unread,
May 12, 2017, 7:07:51 AM5/12/17
to std-proposals


El 11/5/2017 18:19, <philippe...@gmail.com> escribió:
I've decided to dip my toe into the standardization process. As such, I've come up with (what I think is) a small feature I really like. I have to do a lot of programming in [other language] at work, and something I greatly miss when getting back to C++ is the null coalescing operator. It is a quality of life feature that simplifies and compacts patterns of code that are used throughout codebases.

Consider the following conditional operator use case:

Test* get_test() { /*...*/ }

Test* test = (get_test() != nullptr) ? get_test() : new Test();


If `get_test()` has side effects, we may have a problem. We would use the following instead.

Test* test = get_test();
test
= test != nullptr ? test : new Test();


We could instead use a shortcut without side effect, the null coalescing operator ??. 
The left hand side expression is evaluated and compared to nullptr. If it is not nullptr, the evaluation is complete. If it is nullptr, the right hand side expression is evaluated.

Test* test = get_test() ?? new Test();


It can also be a concise way to throw on a null value.

some_pointer ?? throw std::invalid_argument("some_pointer is null.");



What about a library function such as

template <class T, class Func>
T* coalesce(T* x, Func f)
{
     if (x == nullptr)
           return f();
     else
           return x;
}

So coalesce(x, [](){return new T;})   or also the throw use case.
?


These are the most interesting aspects of the feature. I'd like to gather thoughts and comments. Maybe it has already been mentioned in a paper that didn't go through? I'm simply interested in getting the discussion started before writing a paper. If the general consensus is that this feature is desired, maybe you could point me to a committee member that could mentor me?

Thank you,
Philippe

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.

Alberto Barbati

unread,
May 13, 2017, 10:32:22 AM5/13/17
to ISO C++ Standard - Future Proposals

Il giorno venerdì 12 maggio 2017 13:07:51 UTC+2, dgutson ha scritto:

What about a library function such as

template <class T, class Func>
T* coalesce(T* x, Func f)
{
     if (x == nullptr)
           return f();
     else
           return x;
}

 
This is exactly the kind of applications of my recent proposal Controlled Argument Evaluation. With my proposal, you would be able to write a function with the exact same meaning without having to dish out lambdas explicitly.

Alberto

dgutson .

unread,
May 13, 2017, 11:52:32 AM5/13/17
to std-proposals


El 13/5/2017 11:32, "Alberto Barbati" <alberto...@gmail.com> escribió:

Il giorno venerdì 12 maggio 2017 13:07:51 UTC+2, dgutson ha scritto:

What about a library function such as

template <class T, class Func>
T* coalesce(T* x, Func f)
{
     if (x == nullptr)
           return f();
     else
           return x;
}

 
This is exactly the kind of applications of my recent proposal Controlled Argument Evaluation.

This is exactly the kind of scenarios where there isn't any need for change and language is OK as-is, but just to extend the library a bit. My idea of evolution is: languange should stabilize as a consequence of maturity, and expansion should land in the library side.
Whst I showed just requires a few keystrokes.
Except of course for foundamental changes (ie as concepts, coroutines) which is not your proposed case.
Anyway let's not pollute this thread with discussions related to other ones.


With my proposal, you would be able to write a function with the exact same meaning without having to dish out lambdas explicitly.

Alberto

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.

ol...@join.cc

unread,
May 22, 2017, 4:44:40 AM5/22/17
to ISO C++ Standard - Future Proposals
Op vrijdag 12 mei 2017 00:34:39 UTC+2 schreef Ville Voutilainen:
Test* test = get_test(); 
if (!test) 
  test = new Test(); 

Not a one-liner but quite simple. Does this come up often?
In other languages nullable types work a bit differently, would ?: play nice with optional in C++?

Bengt Gustafsson

unread,
May 22, 2017, 3:46:47 PM5/22/17
to ISO C++ Standard - Future Proposals, ol...@join.cc
In javascript you often see the equivalent of:

Test* test = get_test() || new Test();

which almost works in C++ too, except that the return type of || always is bool even if both lhs and rhs are the same pointer type. Changing the return type would however break some code... and I can't see a way around that problem, unfortunately. Back to square one.

Philippe Groarke

unread,
May 22, 2017, 8:20:27 PM5/22/17
to std-pr...@isocpp.org
Since this has already been proposed and refused. Also considering 2 of the major compilers offer it as an extension, which means adding the feature to the language probably would've been trivial. I think it is pretty much a dead end.

Thanks for the comments though.

-- 
You received this message because you are subscribed to a topic in the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this topic, visit https://groups.google.com/a/isocpp.org/d/topic/std-proposals/uNYpDyi7VSA/unsubscribe.
To unsubscribe from this group and all its topics, send an email to std-proposal...@isocpp.org.

To post to this group, send email to std-pr...@isocpp.org.

Tony V E

unread,
May 22, 2017, 8:26:00 PM5/22/17
to Philippe Groarke
If someone convinces the third major compiler to also support it, it might eventually get standardized as it will be de facto standard. 

‎But I don't think it is worth committee time - it isn't a feature that is needed that often, nor does it confer much benefit. 

Sent from my BlackBerry portable Babbage Device
From: Philippe Groarke
Sent: Monday, May 22, 2017 8:20 PM
Subject: Re: [std-proposals] Null coalescing operator

You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.

To post to this group, send email to std-pr...@isocpp.org.
Reply all
Reply to author
Forward
0 new messages