¿Devolver un vacío?
No entiendo por qué este código compila sin error:
#include <iostream>
template <class T>
struct Test
{
static constexpr T f() {return T();}
};
int main()
{
Test<void> test;
test.f(); // Why not an error?
return 0;
}
¿Está bien de acuerdo con el estándar, o es una tolerancia del compilador?
3 answers
Esto parece válido para el borrador del estándar C++11, si miramos la sección 5.2.3
Conversión explícita de tipos (notación funcional) párrafo 2 dice ( énfasis mío):
La expresión T () , donde T es un especificador de tipo simple o typename-specifier for a non-array complete object type or the tipo void , crea un prvalue de la tipo especificado, cuyo valor es el producido por inicialización de valores (8.5) un objeto de tipo T; no se realiza inicialización para el vacío() caso.[...]
La redacción es bastante similar pre C++11 también.
Esto está bien en un constexpr a pesar de que la sección 7.1.5
párrafo 3
dice:
La definición de una función constexpr deberá satisfacer lo siguiente: limitaciones:
, E incluye esta viñeta:
Su tipo de retorno será un literal tipo;
Y void no a literal{[9] {} en[8]}C++11 por la sección 3.9
párrafo 10, pero si luego miramos el párrafo 6 se da una excepción que se ajusta a este caso, se dice:
Si la especialización de plantilla instanciada de una función constexpr plantilla o función miembro de una plantilla de clase no podría satisfacer los requisitos para una función constexpr o un constructor constexpr, esa especialización es no es una función constexpr o constexpr constructor. [Nota: Si la función es una función miembro, todavía ser const como se describe a continuación. - end note] If no specialization of la plantilla daría una función constexpr o constexpr constructor, el programa está mal formado; no se requiere diagnóstico.
Como Casey señaló en el C++14 draft standard void es un literal , esta es la sección 3.9
Tipos párrafo 10 dice:
Un tipo es un tipo literal si es:
E incluye:
- nulo; o
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 10:27:21
Ver la respuesta de @Shafik Yaghmour para la información completa.
El siguiente párrafo prohíbe esto para no plantillas (7.1.5(3)):
La definición de una función
constexpr
deberá satisfacer las siguientes restricciones:
[...]
Su tipo de retorno será un tipo literal o una referencia al tipo literal
Para elaborar, un tipo literal se define en 3.9 (10) como un tipo escalar o una composición de objetos de tipo literal en una matriz o estructura. void
no es un tipo escalar por 3.9 (9).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-09 19:17:02
Su función devuelve el valor de void()
, no está regresando de una función void per se. Está devolviendo un valor NULL
. Lo que estás haciendo es equivalente a esto:
void f() { return void(); }
Esto devuelve un valor void, el único valor void. no puede devolver nada más de una función void porque será de un tipo diferente.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-10 00:30:47