C# null coalescing operator equivalent for c++

2019-02-11 15:49发布

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.

5条回答
混吃等死
2楼-- · 2019-02-11 16:08

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.

查看更多
聊天终结者
3楼-- · 2019-02-11 16:10

How about this?

#define IFNULL(a,b) ((a) == null ? (b) : (a))
查看更多
我只想做你的唯一
4楼-- · 2019-02-11 16:20

Using templates and C++11 lambdas. The first argument (left-hand side) is only evaluated once. The second argument (right-hand side) is only evaluated if the first is false (note that 'if' and '?' statically cast the provided expression to bool, and that pointers have 'explicit operator bool() const' that is equalivent to '!= nullptr')

template<typename TValue, typename TSpareEvaluator>
TValue
coalesce(TValue mainValue, TSpareEvaluator evaluateSpare) {

    return mainValue ? mainValue : evaluateSpare();
}

Example of use

void * const      nonZeroPtr = reinterpret_cast<void *>(0xF);
void * const otherNonZeroPtr = reinterpret_cast<void *>(0xA);

std::cout << coalesce(nonZeroPtr, [&] () { std::cout << "Never called"; return otherNonZeroPtr; }) << "\n";

Will just print '0xf' in the console. Having to write a lambda for the rhs is a little bit of boilerplate

[&] () { return <rhs>; }

but it's the best that one can do if one lacks support by the language syntax.

查看更多
淡お忘
5楼-- · 2019-02-11 16:23

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;
}
查看更多
ゆ 、 Hurt°
6楼-- · 2019-02-11 16:27

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";
查看更多
登录 后发表回答