2009-03-10 6 views
1


[обновление вопроса в соответствии с обновленными требованиями]
Я внедрено следующими функциями, которая должна возвращать либо первый не нулевой элемент или бросить исключение.
Также вы могли бы придумать более классическое и более короткое имя, например «max», «min», «pair»?C++ выбрать первый не нулевой элемент

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

ответ

3

вы можете попробовать сделать следующий

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

Я думаю, вы хотели сделать что-то другое в этом примере кода. Но вы смешали некоторые «нулевые значения» и «значение по умолчанию» – bayda

+0

Не могли бы вы обновить свой ответ в соответствии с обновленным вопросом? –

+0

Где исключение? –

2

Если для Т т е р делает ничего существенного, по-видимому, как вы делаете это в три раза, каждый раз через «select_first_not_empty».

Oracle называет нечто подобное «COALESCE», если вы ищете лучшее имя.

Я не уверен, в чем дело. Если бы я действительно хотел узнать, было ли что-то задано или нет, я бы использовал указатели с нулевым значением, а не ссылки. «NULL» - гораздо лучший показатель намерения не иметь переменную, чем использовать внутриполосное значение, например, 0 или «».

+0

Это будет в основном для указателей и, вероятно, строки. –

2

C# имеет аналогично функционирующий встроенный оператор ??, который, как я считаю, называется coalesce.

в Perl || (логический ИЛИ от короткого замыкания) оператор также имеет аналогичные функциональные возможности: вместо возврата 0 или 1, то возвращается значение первого аргумента, вычисляемое истинный:

0 || 7 

возвращает 7, а не 1 или true, как ожидал программист C \ C++ или C#.

Самое близкое к этому, что C++ имеет встроенный в это алгоритм 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

Мне нужно решение C++ –

+0

Я понимаю, я просто давал вам указатели, чтобы попытаться вспомнить имя, которое вы хотите. Нет встроенной версии C++, и ваша версия выглядит так, как будто она работает. – Eclipse

+0

Я обновил вопрос. Пожалуйста, взгляните еще раз. –