Is there a C++ equivalent for C# null coalescing operator? I am doing too many null checks in my code. So was looking for a way to reduce the amount of null code.
-
12In GCC, it's `a ?: b` but that's non-portable. – MSalters Nov 26 '09 at 15:36
-
@MSalters: That's not quite it, since if `false ?: 123` is `123`, while `coalesce(false, 123)` is `false`. – einpoklum Apr 18 '23 at 08:54
-
@einpoklum: you appear to have a particular definition of `coalesce`. E.g. SQL `COALESCE(NULL, 123)` is `123`. My informal definition is "the first truthy value in a list" – MSalters Apr 18 '23 at 09:19
-
@MSalters it's not me, it's the OP... this question is about C#'s coalesce. I just posted an answer, please see the details there. – einpoklum Apr 18 '23 at 10:02
9 Answers
I just found this: The ?? operator aka the Null Coalescing Operator
You also have it in C/C++ as a GNU extension using the
?:
operator :string pageTitle = getTitle() ?: "Default Title";

- 3,249
- 3
- 24
- 42

- 362
- 3
- 9
-
2New link: https://gcc.gnu.org/onlinedocs/gcc-5.3.0/gcc/Conditionals.html#Conditionals In short, the GNU extension lets you omit the middle of a ternary and that results in the condition becoming the return value in the case where that condition is "non-zero" – Cory-G Feb 21 '20 at 01:56
-
This is incorrect, because `false ?: 123` is `123`, while `coalesce(false, 123)` would be `false`. – einpoklum Apr 18 '23 at 08:56
There isn't a way to do this by default in C++, but you could write one:
in C# the ?? operator is defined as
a ?? b === (a != null ? a : b)
So, the C++ method would look like
Coalesce(a, b) // put your own types in, or make a template
{
return a != null ? a : b;
}

- 12,334
- 7
- 53
- 76
-
25In this method b is evaluated even if a isn't null. This might be a problem if b has side effects. – Amnon Nov 23 '09 at 19:52
-
4@Amnon: Indeed. Consider: `p = Coalesce(p, new int(10));`. Also, it seems in C# the right-hand operand cannot be NULL (can't be checked at compile-time, since there are no nullable types in C++?). On the other hand: is there that much need for it in C++, so that you can't just type `a ? a : b;`? – UncleBens Nov 23 '09 at 21:34
-
5And if it's C++11 or above, use `nullptr`. There's no `null` in C/C++ anyway, only `NULL` is defined in some headers. http://stackoverflow.com/questions/1282295/what-exactly-is-nullptr – Csaba Toth Sep 12 '13 at 18:52
-
@UncleBens: Can you explain why in C# the right-hand operand of cannot be NULL? AFAIK, you can even chain these together ie `A??B??C` in which case it will choose the first non-NULL operand. B is the right-hand operand of `A??B` and it can be NULL, or is it because it is also the left-hand operand of `B??C`? – Lunyx Dec 11 '13 at 03:25
-
1@Lunyx: In the case of `A??B??C`, `B??C` is the right hand operand of the first `??`. In other words, it's equivalent to `A??(B??C)`. Also, there is no restriction that the right hand operator cannot be null, it just results in the whole thing being null. – Cemafor Apr 09 '15 at 00:33
-
-
-
@M.kazemAkhgary Could you elaborate? I don't see how it isn't threadsafe, but perhaps I'm missing something. To me, this code in C++ is a function that takes two pointers (not by reference), so `a` is either null, or it's a pointer to a location in memory. That can't get modified by the caller, because it's a pointer. Admittedly the contents of the memory at that location might change, but the contents of the memory at that location are not accessed (or even dereferenced) by this function. Am I missing something? – McKay Oct 21 '19 at 04:51
-
1Oops, my bad, you are right. Since "a" and "b" are local variables this code is thread safe – M.kazem Akhgary Oct 21 '19 at 16:00
-
@einpoklum Could you elaborate? Perhaps you're missing the comment at the end of the line? Or the lack of a clear null that's already been discussed? Those should be simple enough for you to figure out on your own. If it's something else, let's talk about it. – McKay Apr 18 '23 at 17:26
-
@McKay: The snippet at the bottom is something could be converted into C++, but isn't C++ yet. And the conversion is not trivial. – einpoklum Apr 18 '23 at 17:46
-
@einpoklum it depends on your definition of "trivial". I think especially the non templated version is trivial. The answer was meant to be instructive, not to solve all of the worlds problems. I even have a comment stating a clear limitation of how it isn't c++ yet. I'm sorry it doesn't meet your standards. – McKay Apr 20 '23 at 05:06
Using templates and C++11 lambdas:
template<typename TValue, typename TRhsEvaluator>
TValue coalesce(TValue lhsValue, TRhsEvaluator evaluateRhs) {
return lhsValue ? lhsValue : evaluateRhs();
}
- The first argument (left-hand side) is only evaluated once.
- The second argument (right-hand side) is only evaluated if the first argument is false.
Note that if
and ?
statically cast the provided expression to bool
, and that pointers have a built-in explicit operator bool() const
operator which is equalivent to != nullptr
Example usage:
void * const nonZeroPtr = reinterpret_cast<void *>(0xF);
void * const otherNonZeroPtr = reinterpret_cast<void *>(0xA);
std::cout << coalesce(nonZeroPtr, [&] () {
std::cout << "Side-effect. Should never be printed" << std::endl;
return otherNonZeroPtr;
}) << std::endl;
The code above will only print 0xf
to the console.
The right-hand side needs to be wrapped inside a lambda - we cannot avoid that boilerplate. Really the language should provide a null coalescing operator out of the box.

- 59
- 1
- 3
-
4This is the only answer that offers identical semantics of a null coalescing operator. It's probably rarely worth the fuss, though. Really, this feature just needs to be in the language. – Edward Brey Oct 15 '16 at 12:28
Just want to expand @Samuel Garcia's answer by generalising the template and adding helper macros to cut down on lambda boilerplate:
#include <utility>
namespace coalesce_impl
{
template<typename LHS, typename RHS>
auto coalesce(LHS lhs, RHS rhs) ->
typename std::remove_reference<decltype(lhs())>::type&&
{
auto&& initialValue = lhs();
if (initialValue)
return std::move(initialValue);
else
return std::move(rhs());
}
template<typename LHS, typename RHS, typename ...RHSs>
auto coalesce(LHS lhs, RHS rhs, RHSs ...rhss) ->
typename std::remove_reference<decltype(lhs())>::type&&
{
auto&& initialValue = lhs();
if (initialValue)
return std::move(initialValue);
else
return std::move(coalesce(rhs, rhss...));
}
}
#define COALESCE(x) (::coalesce_impl::coalesce([&](){ return ( x ); }))
#define OR_ELSE ); }, [&](){ return (
Using the macros, you can just:
int* f();
int* g();
int* h();
int* x = COALESCE( f() OR_ELSE g() OR_ELSE h() );
I hope this helps.

- 49
- 2
Here are two macros to replicate the ??
and ?.
operators. These macros ensure:
- Arguments are evaluated only once.
- The second param is only evaluated if the first param is null.
- Macro variables are internally scoped using compile-time-removed lambda syntax. This avoids macro variable collisions.
Example usage:
COA( nullPtr, goodPtr )->sayHello();
COA( nullPtr, COA( nullPtr, goodPtr ) )->sayHello();
COACALL( goodPtr, sayHello() );
COACALL( nullPtr, sayHello() );
COACALL( COA( nullPtr, goodPtr ), sayHello() );
Definitions:
#define COA(a, b) ([&](){ auto val = (a); return ((val) == NULL ? (b) : (val)); }())
#define COACALL(a, b) ([&](){ auto val = (a); if (val) (val->b); }());
Note: COACALL
does not return results. Only use with void calls or alter to fit your needs.

- 1,025
- 14
- 26
-
This COALESCE implementation is simple and avoids other answers drawbacks. Should be rated higher – zzz Nov 09 '21 at 23:35
How about this?
#define IFNULL(a,b) ((a) == null ? (b) : (a))

- 44,807
- 15
- 124
- 208
-
3beware of IFNULL(a++, b) Yeah, I realize you'd want to beware of that anyway if you think a might be null. IFNULL(SomeClass.DoSomethingReallyLong(), "") causes problems too. – McKay Nov 23 '09 at 19:40
-
1Good point-- serves me right for being lazy. Using a template method is definintely the way to go here, since it avoids side effects and will have equivalent performance (or better). I'm going to add a +1 on @McKay's solution now. :-) – Justin Grant Nov 23 '09 at 20:27
-
4A function template doesn't necessarily have equal or better performance. This "short-circuits" (`b` is not evaluated unless `a` is null), whereas a function's arguments are always evaluated. – Steve Jessop Nov 23 '09 at 22:02
-
@Steve Correct Justin's code would "perform" better in the case of IFNULL("", SomeClass.DoSomethingReallyLong()); – McKay Nov 23 '09 at 22:25
-
2Also a good point. But, I think the most common use case (at least in C# when I've used the ?? operator) is where a is more expensive (e.g. database call, XML parsing) than b. Often b is a constant, like 0 or "". So I suspect the template would win out most of the time. Plus, unless you know how the macro is implemented, the double-execution wouldn't be obvious to the macro's caller, while function-call semantics are well-known so anyone with an expensive b would know to skip the function and just manually create a temporary variable. Funny, I'm arguing against my own answer... :-) – Justin Grant Nov 23 '09 at 22:37
-
And I was arguing against my own. Both have their advantages and drawbacks. – McKay Oct 26 '10 at 22:52
-
This should be the right answer. Its the only one that doesn't always evaluate (b), and doesn't require some verbose syntax usage side. Macros aren't usually the way to go, but some people are way too dogmatic about it. – c z Jun 14 '16 at 21:49
-
2You could wrap in a lambda, then `a` won't ever be evaluated twice. `#define IFNULL(a, b) ([&](){ auto val = (a); return ((val) == NULL ? (b) : (val)); }()) ` – Cory-G Mar 16 '18 at 06:21
There is a GNU GCC extension that allows using ?:
operator with middle operand missing, see Conditionals with Omitted Operands.
The middle operand in a conditional expression may be omitted. Then if the first operand is nonzero, its value is the value of the conditional expression.
Therefore, the expression
x ? : y
has the value of
x
if that is nonzero; otherwise, the value ofy
.This example is perfectly equivalent to
x ? x : y
In this simple case, the ability to omit the middle operand is not especially useful. When it becomes useful is when the first operand does, or may (if it is a macro argument), contain a side effect. Then repeating the operand in the middle would perform the side effect twice. Omitting the middle operand uses the value already computed without the undesirable effects of recomputing it.
This extension is also supported by clang. However, you should check with the compiler you're using and portability requirements for your code before using the extension. Notably, MSVC C++ compilers do not support omitted operands in ?:
.
See also related StackOverflow discussion here.

- 19
- 2
Just to add to the answers mentioning the ?:
operator (the "Elvis operator"): I sometimes use a helper function together with this operator that gets the underlying value of a pointer or std::optional
or similar types that "wrap" a value and have a boolean conversion to indicate the presence of a value. For example:
template <typename T>
constexpr T coalesce (std::optional<T> opt) {
return *opt;
}
template <typename T>
constexpr T coalesce (T fallback) {
return fallback;
}
std::optional<int> opt1{5};
std::optional<int> opt2;
int val1 = coalesce(opt1 ?: 0);
int val2 = coalesce(opt2 ?: 0);
The only drawback is that this must be used carefully and won't give you a static check of correct use. E.g. you could just do coalesce(opt2)
without the ?: fallback
and that would be the same as doing *opt2
without first checking whether it contains anything. So the name coalesce
is sort of misleading, but when used correctly it looks self-explanatory (and pretty neat) in my opinion.

- 1,605
- 3
- 18
- 25
Reminder: C# coalesce semantics
The semantics of ??
, the coalescing operator of C#, are:
p ?? q
Here,
p
is the left andq
is the right operand of [the]??
operator. The value ofp
can be nullable type, but the value of q must be non-nullable type. If the value ofp
isnull
, then it returns the value of q. Otherwise, it will return the value ofp
.
A C++ implementation
We first note that C++ cannot use ??
as an identifier; nor is the preprocessor willing to let us define a macro with this name. So, lets use coalesce
as the identifier instead.
We need to define coalesce
somehow as an infix operator with the requested semantics. This is doable with a combination of operator overloading and a macro for tying things together, so that we can write:
int* p = // whatever
int* q = // whatever
int* result = p coalesce q;
Here's an implementation:
#include <functional>
namespace detail {
struct coalesce_op {};
template <typename T>
struct coalesce_op_primed {
T&& lhs;
constexpr T&& operator+(T&& rhs) {
return (lhs == nullptr) ? rhs : lhs;
}
};
template <typename T>
constexpr coalesce_op_primed<T> operator+(T&& t, coalesce_op)
{
return coalesce_op_primed<T>{std::forward<T>(t)};
}
} // namespace detail
#define coalesce + detail::coalesce_op{} +
See it in action on GodBolt.
Notes:
- There isn't any short-circuit logic, i.e.
q
is evaluated even if it isn't used. One could write a macro with short-circuit logic, but it wouldn't be an infix operator. - We cannot use the GNU C extensions'
?:
Elvis-operator, as its semantics are different. It will consider a non-null false value as reason to choose the RHS operand, i.e.false ?: 123
will yield123
, whilefalse ?? 123
isfalse
using the C# coalesce semantics. - I did not try to make this work for
std::optional
's, detectingnullopt
. If that is required, it should also be possible with some if-constexpr or tagged-dispatch TMP.

- 118,144
- 57
- 340
- 684