У меня есть следующий шаблон
template<typename T> void f(T t) { }
И я хочу передать адрес конкретной его специализации функции C
g(&f<int>);
Но поскольку я хочу быть переносимым, я хочу, чтобы соглашение о вызовах "f" совпадало с соглашением о C. Поэтому я экспериментировал, как языковая связь влияет на соглашение о вызовах, и нашел
- Языковая связь типа функции влияет на соглашение о вызовах для использования
- Языковая связь имени функции влияет на искажение
В разделе о языковых связях в спецификации C ++ написано
В спецификации связи указанная языковая связь применяется к типам функций всех объявлений функций, имен функций с внешней связью и имен переменных с внешней связью, объявленных в спецификации связи.
Таким образом, чтобы предотвратить отключение искажения, которое необходимо для шаблонов, чтобы отличать различные специализации друг от друга в объектном файле, я сделал следующее
extern "C" {
/* function name will not be affected */
template<typename T> static void f(T t) { }
}
Но это дает мне ошибку компилятора, говорящую о том, что шаблоны не могут иметь связи на языке Си, что, как я понимаю, означает, что они жалуются на тип функции шаблона функции. И на самом деле я нашел спецификацию, чтобы сказать
Шаблон, явная специализация шаблона (14.7.3) и частичная специализация шаблона класса не должны иметь связи C
Теперь для меня очевидно, что мы не хотим менять связь name , потому что мы полагаемся на калечащие работы. Но какова причина запрета на изменение связи type ? Кажется, это ограничивает нас в необходимости использовать соглашение о вызовах C ++; кто-то знает причину, и есть ли легкий способ обойти мою первоначальную цель?
Я изменил способ, которым я пытаюсь дать привязку только к типу, следующим образом
extern "C" typedef void ftype(int);
template<typename T>
ftype f;
И это отлично работает. К сожалению, я не вижу способа определить f
при использовании этой техники. Но в любом случае, никакой компилятор, который я пробовал, диагностирует это (пробовал EDG / comeau, GCC и clang), даже если это выглядит точно так же, как и раньше: имя не должно иметь связи на языке C, но имеет только тип.
Может кто-нибудь объяснить это?