Это следующий вопрос для ответа на Можно ли ввести typedef в указатель-на-extern- Тип "C" в шаблоне?
Этот код не компилируется с помощью g++
, Visual C/С++ и Comeau C/С++ с тем же сообщением об ошибке:
#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++ говорит "error: template with C linkage", Visual C/С++ испускает ошибку компилятора C2894, а Comau C/С++ говорит: error: эта декларация может не иметь ссылку "C" extern.
Дело в том, что все довольны:
#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;
}
Раздел 7.5, Спецификации привязки, Стандартные состояния С++:
Связка языка C игнорируется для имен членов класса и функции-члена тип функций класса.
И это даже дает пример:
extern "C" {
class X {
void mf(); // the name of the function mf and the member
// function 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
};
}
Если шаблоны разрешены во внешних блоках "C" , то функции-члены экземпляров будут иметь ссылку на С++.
Почему тогда главу 14, Шаблоны, состояния Стандарта С++ 98:
Название шаблона может иметь привязку (3.5). Шаблон, явная специализация шаблона (14.7.3) и частичная специализация шаблона шаблона не должны иметь C-ссылки.
Что означает, что шаблон "может иметь" связь? Что такое привязка шаблонов?
Почему явно запрещено иметь шаблон с C-связью, когда класс в порядке, и все функции-члены экземпляров шаблона (по умолчанию конструктор, деструктор и перегрузка оператора присваивания) имели бы ссылку на С++?