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(), dondeTes 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_typees un tipo de objeto, el objeto tiene un valor inicializado; De lo contrario, no se realiza ninguna inicialización. Sinew_typees (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
autotipo
- Declarar
void* voidPtrfunciona bien, peroremove_pointer_t<decltype(voidPtr)> decltypeVoiderrores:
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
decltypeonoexcept: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
returnde 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);
}