Domanda


[aggiornamento delle domande in base ai requisiti aggiornati]
Ho implementato la seguente funzione che dovrebbe restituire il primo elemento non nullo o generare un'eccezione.
Potresti anche inventare un nome più classico e più breve come 'max', 'min', 'pair'?

template <typename T>
T select_first_not_empty( const T& a, const T&b )
{
    static T null = T();

    if ( a == null && b == null )
        throw std::runtime_error( "null" );

    return
        a != null ? a : b;
}

int main()
{
    const int a1 = 2;
    const int b1 = 0;

    const int* a2 = 0;
    const int* b2 = new int(5);

    const std::string a3 = "";
    const std::string b3 = "";

    std::cout << select_first_not_empty( a1, b1 ) << std::endl;
    std::cout << select_first_not_empty( a2, b2 ) << std::endl;
    std::cout << select_first_not_empty( a3, b3 ) << std::endl;

    return 0;
}
È stato utile?

Soluzione

puoi provare a fare il prossimo

template < typename T >
T get_valuable( const T& firstValue, 
                const T& alternateValue, 
                const T& zerroValue = T() )
{
    return firstValue != zerroValue ? firstValue : alternateValue;
}

// usage
char *str = "Something"; // sometimes can be NULL
std::string str2 ( get_valuable( str,  "" ) );

// your function
template <typename T>
T select_first_not_empty( const T& a, 
                          const T& b, 
                          const T& zerroValue = T() )
{
    const T result = get_valuable( a, b, zerroValue );
    if ( result == zerroValue )
    {
        throw std::runtime_error( "null" );
    }
    return result;
}

Altri suggerimenti

C # ha un operatore incorporato allo stesso modo ?? , che credo sia chiamato coalescenza.

L'operatore Perl || (OR logico di cortocircuito) ha anche funzionalità simili: invece di restituire 0 o 1, restituisce il valore del primo argomento valutando true:

0 || 7

restituisce 7, non 1 o true come si aspetterebbe un programmatore C \ C ++ o C #.

La cosa più vicina a questa che C ++ ha incorporato è l'algoritmo find_if:

vector<int> vec;
vec.push_back(0);
vec.push_back(0);
vec.push_back(7);

vector<int>::iterator first_non_0 = 
    find_if(vec.begin(), vec.end(), bind2nd(not_equal_to<int>(), 0));

Se il ctor per T fa qualcosa di significativo, sembra che tu lo stia facendo tre volte ogni volta attraverso " select_first_not_empty " ;.

Oracle chiama qualcosa di simile "COALESCE", se stai cercando un nome migliore.

Non sono sicuro di quale sia il punto, però. Se volessi davvero sapere se qualcosa è stato impostato o meno, utilizzerei i puntatori nullable anziché i riferimenti. & Quot; NULL " è un indicatore di gran lunga migliore dell'intenzione di non avere la variabile impostata piuttosto che utilizzare un valore in-band come 0 o " " ;.

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