c++ - redes - ¿Construcción de un tipo vacío?
informacion mediatica (5)
No hay lugar para void () en C ++, ¿verdad?
Como expresión, void()
es válido en C ++.
Del estándar, $5.2.3/2 Explicit type conversion (functional notation) [expr.type.conv]
:
La expresión
T()
, dondeT
es un especificador de tipo simple o un especificador de nombre de tipo para un tipo de objeto completo sin arreglo o el tipo devoid
(posiblemente calificado por cv), crea un valor predeterminado del tipo especificado, cuyo valor es ese produjo mediante la inicialización de valor (8.5) un objeto de tipoT
; no se realiza ninguna inicialización para el casovoid()
.
Desde cppreference.com :
nuevo tipo ( )
Si
new_type
es un tipo de objeto, el objeto tiene un valor inicializado; De lo contrario, no se realiza ninguna inicialización. Sinew_type
es (posiblemente cv-calificado)void
, la expresión es un prvaluevoid
.
Me dieron una pieza de código que usa void()
como argumento. El código no compila ... obviamente?
¿Podemos instanciar algo de tipo void
? Creía que la respuesta era no, con la excepción de un void*
. Por ejemplo:
- Escribiendo la función
void askVoid(void param) {}
errores:
Un parámetro puede no tener un tipo de
void
- Escribiendo la función
void askNaught() {}
y llamándola con los errores askNaught (void ()) `
error C2660:
takeNaught
: la función no toma 1 argumentos
- Escribiendo la plantilla de función
template <typename T> void takeGeneric(T param) {}
y llamándola con lostakeGeneric(void())
:
error C2893: Error al especializar la plantilla de función
void takeGeneric(T)
- Declarando errores
void voidType
:
No se permite el tipo incompleto
- Declarando
auto autoVoid = void()
errores:
No se puede deducir
auto
tipo
- Declarar
void* voidPtr
funciona bien, peroremove_pointer_t<decltype(voidPtr)> decltypeVoid
errores:
error C2182:
decltypeVoid
: uso ilegal de tipovoid
Eso es todo, ¿verdad? No hay lugar para void()
en C ++, ¿verdad? Esto es solo un código malo que me han dado, ¿verdad?
C ++ (y digo C ++, no C) permite que las funciones ( §6.6.3 coma 2 ) con tipo de retorno de void
devuelvan una expresión de void
, es decir:
void foo() { return void(); }
¡Pero note que no está construyendo un void
temporal!
La expresión void()
es un valor predefinido de tipo void
y se puede utilizar en cualquier lugar en el que se pueda usar dicha expresión, que [basic.fundamental]/9 proporciona una lista útil:
- Como una expresión-declaración:
void();
- Como el segundo o tercer operando de un operador condicional:
true ? throw 1 : void()
true ? throw 1 : void()
- Como operando del operador de coma:
++it1, void(), ++it2
- Como el operando de
decltype
onoexcept
:using my_void = decltype(void()); static_assert(noexcept(void()), "WAT");
using my_void = decltype(void()); static_assert(noexcept(void()), "WAT");
- En una declaración de
return
de una función que devuelve (posiblemente cv-calificado)void
:const void f() { return void(); }
const void f() { return void(); }
- Como un operando de una conversión explícita a (posiblemente cv calificado)
void
:static_cast<const void>(void())
Una expresión de tipo void
también se puede utilizar como el operando de typeid
, pero void()
en particular se analizaría como un tipo, no una expresión, en este contexto.
Puede usar void()
como tipo llamable, como ejemplo std::function<void()> f;
Es una declaración válida.
Además, a partir de 8.3.5/4 :
Una lista de parámetros que consiste en un único parámetro sin nombre de tipo no dependiente void es equivalente a una lista de parámetros vacía.
Eso significa que esto es válido:
template<typename T>
struct F;
template<typename R, typename... A>
struct F<R(A...)> { };
int main () {
F<void(void)> s;
}
Aquí no está creando una instancia de nada de tipo void
, pero lo está utilizando (permítanme decirlo) como una lista de parámetros de un tipo invocable.
No estoy seguro de si esto responde a su pregunta, no he aclarado cuál es realmente la pregunta.
Puedes tomar un void()
como parámetro de función:
void test(void()) { ... }
Que se expande a:
void test(void (*)())
Que es un puntero de función a un método que devuelve void y no toma argumentos.
Ejemplo completo:
void abc() {}
void test(void()) { }
int main() {
test(abc);
}