2009-03-10 8 views
1


[Màj question selon les exigences mises à jour]
J'ai mis en fonction suivante qui devrait revenir soit premier élément ou pas jeter nulle une exception.
Aussi pourriez-vous inventer des noms plus classiques et plus courts comme «max», «min», «paire»?C++ sélectionnez d'abord pas un élément nul

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

Répondre

3

vous pouvez faire ensuite

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; 
} 
+0

Je suppose que vous vouliez faire quelque chose d'autre dans cet exemple de code. Mais vous avez mélangé quelques "valeur zéro" et "valeur par défaut" – bayda

+0

Pourriez-vous mettre à jour votre réponse en fonction de la question mise à jour? –

+0

Où est l'exception Thorw? –

2

Si le cteur T fait quelque chose d'important, il semble que vous faites trois fois à chaque fois par « select_first_not_empty ».

Oracle appelle quelque chose de similaire "COALESCE", si vous cherchez un meilleur nom.

Je ne suis pas sûr de ce que le point est, cependant. Si je voulais vraiment savoir si quelque chose était défini ou non, j'utiliserais des pointeurs nullables plutôt que des références. "NULL" est un meilleur indicateur de l'intention de ne pas avoir l'ensemble de variables que d'utiliser une valeur dans la bande comme 0 ou "".

+0

Ce sera surtout pour les pointeurs et probablement des chaînes. –

2

C# a un opérateur intégré fonctionnant de manière similaire ??, que je crois est appelé coalesce.

opérateur Perl || (OU logique de court-circuit) comporte également une fonctionnalité similaire: au lieu de retour 0 ou 1, elle renvoie la valeur du premier argument évaluer à vrai:

0 || 7 

retours 7, pas 1 ou true en tant que programmeur C \ C++ ou C# attendrait.

La chose la plus proche de ce que C++ a construit est l'algorithme 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)); 
+0

J'ai besoin de la solution C++ –

+0

Je me rends compte que je ne faisais que vous donner des conseils pour essayer de trouver le nom que vous souhaitez. Il n'y a pas de version C++ intégrée, et votre version a l'air de fonctionner. – Eclipse

+0

J'ai mis à jour la question. S'il vous plaît jeter un oeil à nouveau. –

Questions connexes