sociales redes mediatica informacion c++ void

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() , donde T es un especificador de tipo simple o un especificador de nombre de tipo para un tipo de objeto completo sin arreglo o el tipo de void (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 tipo T ; no se realiza ninguna inicialización para el caso void() .

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. Si new_type es (posiblemente cv-calificado) void , la expresión es un prvalue void .

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:

  1. Escribiendo la función void askVoid(void param) {} errores:

Un parámetro puede no tener un tipo de void

  1. Escribiendo la función void askNaught() {} y llamándola con los errores askNaught (void ()) `

error C2660: takeNaught : la función no toma 1 argumentos

  1. Escribiendo la plantilla de función template <typename T> void takeGeneric(T param) {} y llamándola con los takeGeneric(void()) :

error C2893: Error al especializar la plantilla de función void takeGeneric(T)

  1. Declarando errores void voidType :

No se permite el tipo incompleto

  1. Declarando auto autoVoid = void() errores:

No se puede deducir auto tipo

  1. Declarar void* voidPtr funciona bien, pero remove_pointer_t<decltype(voidPtr)> decltypeVoid errores:

error C2182: decltypeVoid : uso ilegal de tipo void

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 o noexcept : 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); }