Esta es una pregunta de seguimiento a an answer a Is it possible to typedef a pointer-to-extern-“C”-function type within a template?¿Por qué las plantillas no pueden estar dentro de bloques externos "C"?
Este código falla al compilar con g++
, Visual C/C++, y Comeau C/C++ con básicamente el mismo mensaje de error:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
template <typename return_t_, typename arg1_t_>
struct test {
static void foo(return_t_ (*)(arg1_t_)) { }
};
}
int main()
{
test<int, int>::foo(&do_stuff);
return EXIT_SUCCESS;
}
g ++ dice "error: plantilla con enlace C", Visual C/C++ emite el error de compilación C2894, y Comeau C/C++ dice "error: esta declaración puede no tener un enlace externo" C ".
La cosa es que todos están contentos con:
#include <cstdlib>
extern "C" {
static int do_stuff(int) {
return 3;
}
struct test {
static void foo(int (*)(int)) { }
};
}
int main()
{
test::foo(&do_stuff);
return EXIT_SUCCESS;
}
Sección 7.5, especificaciones de vinculación, del estándar de C++ afirma:
A C language linkage is ignored for the names of class members and the member function type of class member functions.
E incluso da el ejemplo:
extern "C" {
class X {
void mf(); // the name of the function mf and the member
// function's type have C++ language linkage
void mf2(void(*)()); // the name of the function mf2 has C++ language
// linkage; the parameter has type pointer to C function
};
}
Si se permitieron plantillas en bloques externos "C", entonces las funciones miembro de las instancias tendrían C++ l inkage.
Por qué, entonces, qué capítulo 14, plantillas, del C++ 98 estado estándar:
A template name may have linkage (3.5). A template, a template explicit specialization (14.7.3), and a class template partial specialization shall not have C linkage.
¿Qué significa que una plantilla "puede" tener vinculación? ¿Qué es el enlace de la plantilla?
¿Por qué está explícitamente prohibido tener una plantilla con vinculación C, cuando una clase es correcta y todas las funciones miembro de instancias de la plantilla (el constructor predeterminado, el destructor y la sobrecarga del operador de asignación) tendrían un enlace C++?
Ah, se encontró que la cláusula que prohibe plantillas de tener vinculación C! –