¿Hay un C++ equivalente para C# nulo coalescente operador? Estoy haciendo demasiadas comprobaciones nulas en mi código. Así que estaba buscando una forma de reducir la cantidad de código nulo.C# nulo coalescente operador equivalente para C++
Respuesta
No hay una manera de hacer esto de forma predeterminada en C++, pero se puede escribir uno:
en C# del ?? operador se define como
a ?? b === (a != null ? a : b)
Por lo tanto, el método C++ se vería
Coalesce(a, b) // put your own types in, or make a template
{
return a != null ? a : b;
}
En este método b se evalúa incluso si a no es nulo. Esto podría ser un problema si b tiene efectos secundarios. – Amnon
@Amnon: De hecho. Considere: 'p = Coalesce (p, new int (10));'. Además, parece que en C#, el operando de la derecha no puede ser NULL (no se puede verificar en tiempo de compilación, ya que no hay ningún tipo de NULL en C++). Por otro lado, ¿existe tanta necesidad en C++, por lo que no puede simplemente escribir 'a? a: b; '? – UncleBens
Y si es C++ 11 o superior, use 'nullptr'. No hay 'null' en C/C++ de todos modos, solo' NULL' se define en algunos encabezados. http://stackoverflow.com/questions/1282295/what-excaly-is-nullptr –
¿Qué tal esto?
#define IFNULL(a,b) ((a) == null ? (b) : (a))
cuidado con IFNULL (a ++, b) Sí, me doy cuenta de que querrías tener cuidado con eso de todos modos si crees que podría ser nulo. IFNULL (SomeClass.DoSomethingReallyLong(), "") causa problemas también. – McKay
Buen punto-- me sirve para ser flojo. Usar un método de plantilla definitivamente es el camino a seguir aquí, ya que evita los efectos secundarios y tendrá un rendimiento equivalente (o mejor). Voy a agregar un +1 en la solución de @ McKay ahora. :-) –
Una plantilla de función no tiene necesariamente un rendimiento igual o mejor. Estos "cortocircuitos" ("b" no se evalúan a menos que "a" sea nulo), mientras que los argumentos de una función siempre se evalúan. –
Acabo de encontrar esto: The ?? operator aka the Null Coalescing Operator
También tiene en C y C++ como una extensión de GNU con el “:” operador:
cadena pageTitle = getTitle() ?: "Título predeterminado";
Uso de plantillas y C++ 11 lambdas. El primer argumento (lado izquierdo) solo se evalúa una vez. El segundo argumento (lado derecho) solo se evalúa si el primero es falso (tenga en cuenta que 'if' y '?' Expresan estáticamente la expresión proporcionada a bool, y que los punteros tienen 'operador explícito bool() const' que es equalivent a '! = nullptr')
template<typename TValue, typename TSpareEvaluator>
TValue
coalesce(TValue mainValue, TSpareEvaluator evaluateSpare) {
return mainValue ? mainValue : evaluateSpare();
}
Ejemplo de uso
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";
se acaba de imprimir '0xf' en la consola. Tener que escribir una lambda de los RHS es un poco repetitivo de
[&]() { return <rhs>; }
pero es lo mejor que uno puede hacer si uno carece de apoyo de la sintaxis del lenguaje.
Esta es la única respuesta que ofrece la semántica idéntica de un operador coalescente nulo. Sin embargo, probablemente nunca valga la pena el alboroto. Realmente, esta característica solo necesita estar en el idioma. –
Sólo quiero ampliar la respuesta de @Samuel García mediante la generalización de la plantilla y la adición de macros de ayuda para reducir el lambda repetitivo:
#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 (
El uso de las macros, puede simplemente:
int* f();
int* g();
int* h();
int* x = COALESCE(f() OR_ELSE g() OR_ELSE h());
I espero que esto ayude.
- 1. C# ?? nulo coalescente operador LINQ
- 2. C# ?? nulo coalescente operador pregunta
- 3. ¿Hay un equivalente Python del operador C# nulo-coalescente?
- 4. atomicidad de C# coalescente operador
- 5. Posible anular operador nulo-coalescente?
- 6. ?? Operador coalescente nulo -> ¿Qué significa coalescencia?
- 7. ¿Un operador de asignación coalescente nulo?
- 8. nulo-coalescente en Javascript?
- 9. precedencia de operador extraño con ?? (operador coalescente nulo)
- 10. Ruby's equivalente a C# 's ?? operador
- 11. Comprender el operador coalescente nula (??)
- 12. Delphi - ¿Equivalente al operador ternario de C#?
- 13. equivalente de PowerShell del operador C# "is"?
- 14. DoEvents equivalente para C++?
- 15. Operador coalescente nulo dando conversión especificada no es válido int corto
- 16. C# si es nulo, entonces nulo expresión
- 17. ¿Mal uso del operador de fusión nulo?
- 18. operador + para matrices en C++
- 19. C# operador de alcance
- 20. C++ [&] operador
- 21. Equivalente al comando C# 'as' en C++?
- 22. C# Uri.EscapeDatastring() equivalente para Java
- 23. Equivalente a #region para C++
- 24. Equivalente a window.setTimeout() para C++
- 25. MonoTouch.Dialog equivalente para Objective C?
- 26. equivalente C# para Delphi de
- 27. El operador + = con tipos anulables en C#
- 28. C++ CString equivalente en C#
- 29. C equivalente de C++ STL
- 30. ¿Hay un operador C# IN?
En GCC, es 'a?: B' pero eso no es portátil. – MSalters