Domanda

C'è un C ++ equivalente per l'operatore C # nullo coalescenza? Sto facendo troppi controlli nulli nel mio codice. Quindi, era alla ricerca di un modo per ridurre la quantità di codice nullo.

È stato utile?

Soluzione

Non è un modo per fare questo per impostazione predefinita in C ++, ma si potrebbe scrivere uno:

in C # il ?? operatore è definito come

a ?? b === (a != null ? a : b)

Quindi, il metodo C ++ sarà simile

Coalesce(a, b) // put your own types in, or make a template
{
    return a != null ? a : b;
}

Altri suggerimenti

Ho appena trovato questo: Il ?? operatore alias il Null coalescenza Operatore

  

Hai anche in C / C ++ come un'estensione GNU utilizzando il ?:   operatore:

string pageTitle = getTitle() ?: "Default Title";

Utilizzo dei modelli e C ++ 11 lambda. Il primo argomento (lato sinistro) viene valutato solo una volta. Il secondo argomento (lato destro) viene valutata solo se il primo è falso (si noti che 'se' e '?' Cast staticamente l'espressione fornita al bool, e che i puntatori hanno 'esplicito bool operator () const' che è equalivent a '! = nullptr')

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

    return mainValue ? mainValue : evaluateSpare();
}

Esempio di utilizzo

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

Sarà basta stampare '0xf' nella console. Dovendo scrivere un lambda per i RHS è un po 'di boilerplate

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

ma è il meglio che si può fare se uno manca il supporto per la sintassi del linguaggio.

Che ne dici di questo?

#define IFNULL(a,b) ((a) == null ? (b) : (a))

Voglio solo di ampliare la risposta di @Samuel Garcia generalizzando il modello e l'aggiunta di macro di supporto per ridurre il 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 (

Utilizzando le macro, si può semplicemente:

int* f();
int* g();
int* h();

int* x = COALESCE( f() OR_ELSE g() OR_ELSE h() );

Spero che questo aiuta.

C'è un'estensione GNU GCC che permette di utilizzare all'operatore ?: con operando metà mancante, vedi condizionali con Omesso Operandi .

  

L'operando medio in un'espressione condizionale può essere omessa. poi, se   il primo operando è diverso da zero, il suo valore è il valore della   espressione condizionale.

     

Di conseguenza, l'espressione

     

x ? : y

     

ha il valore di x se questo è diverso da zero; altrimenti, il valore di   y.

     

Questo esempio è perfettamente equivalente a

     

x ? x : y

     

In questo semplice caso, la possibilità di omettere l'operando mezzo   non è particolarmente utile. Quando diventa utile è quando il primo   operando fa, oppure può (se si tratta di un argomento macro), contengono un lato   effetto. Quindi ripetendo l'operando in mezzo effettuerebbe il   effetto collaterale due volte. Tralasciando l'operando mezzo già utilizza il valore   calcolato senza gli effetti indesiderati della recomputing esso.

Questa estensione è anche supportato da clang . Tuttavia, si dovrebbe verificare con il compilatore che si sta utilizzando e le esigenze di portabilità per il codice prima di utilizzare l'estensione. In particolare, MSVC C ++ compilatori non supportano operandi omesse ?:.

Si veda anche legati discussione StackOverflow qui .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top