C++ selecione primeiro elemento não nulo
Pergunta
[pergunta atualização de acordo com actualizado requisitos]
Eu tenho implementado seguinte função, que deve retornar o primeiro elemento não nulo ou lançar uma exceção.
Também você poderia inventar mais clássico e mais curto do nome como 'max', 'min', 'par'?
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;
}
Solução
você pode tentar fazer a seguir
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;
}
Outras dicas
C# tem um operador interno de funcionamento semelhante ??
, que acredito ser chamado Coalesce.
Perl's ||
(O operador lógico de curto-circuito também possui funcionalidade semelhante: em vez de retornar 0 ou 1, ele retorna o valor do primeiro argumento que avalia para true:
0 || 7
retorna 7, não 1 ou true
Como um programador C C ++ ou C# esperaria.
A coisa mais próxima disso que o C ++ construiu é o 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 o construtor para T faz nada de significativo, ele aparece como você está fazendo isso três vezes, a cada vez, através de "select_first_not_empty".
Oracle chamadas algo semelhante "UNIÃO", se você está à procura de um nome melhor.
Eu não tenho certeza do que o ponto é, no entanto.Se eu realmente queria saber se algo foi definido ou não, eu usaria anulável ponteiros em vez de referências."NULO" é um indicador muito melhor do que a intenção não tenha o conjunto de variáveis que usar uma faixa de valor como 0 ou "".