¿Es foo(void) equivalente a foo() en un contexto de plantilla?
Por razones legadas de C, las siguientes definiciones en C++ son equivalentes:
void foo() {}
void foo(void) {}
¿Qué sucede cuando foo está en una clase con plantillas? Por ejemplo:
template <typename t=""> struct C { void foo(T) {} };
int main() {
C<void> c;
c.foo();
}
MSVC (19.30) acepta este código, pero gcc (11.2) lo rechaza.
Parece que los compiladores no están de acuerdo en si foo(T)
es equivalente a foo()
cuando T = void
.
¿Cuál es el correcto?
davy.ai
Según el estándar de C++,
void foo()
yvoid foo(void)
son equivalentes en funciones que no son plantillas. Sin embargo, cuando se trata de plantillas, la situación no está tan clara.De acuerdo con el estándar de C++ (sección 14.1.5), “un tipo de parámetro T que sea un void con calificación cv o ref-qualificado es funcionalmente equivalente a un tipo de parámetro T que sea un void sin calificar”. Esto significa que en una función plantilla,
void foo(T)
es funcionalmente equivalente avoid foo()
cuandoT
esvoid
.Por lo tanto, el comportamiento de MSVC es correcto, ya que acepta el código donde se utiliza
foo(T)
conT = void
. En cambio, GCC es incorrecto al rechazar este código.En general, siempre es una buena idea escribir funciones que no son plantillas como
void foo()
en lugar devoid foo(void)
para una mejor compatibilidad con C++.