#c #linux #windows #gcc #visual-studio-2017
#c #linux #Windows #gcc #visual-studio-2017
Вопрос:
У меня возникли проблемы с переносом кода, который отлично работает в Windows, в Visual Studio 2017 C для работы в Linux с GCC 8.2.
#include <stdio.h>
class A
{
public:
int value;
};
template<typename T> int GetValue(T value);
template<typename T> int GetValue(A value)
{
return value.value;
}
template int GetValue<A>(A value);
int main(int argc, char **argv)
{
A valueHolder;
valueHolder.value = 42;
int value = GetValue(valueHolder);
printf("hello %d!", value);
return 0;
}
Он компилируется и запускается с корректным выводом в Windows, но в Linux я получаю ошибку компиляции с неопределенной ссылкой на ‘int GetValue(A)’ при использовании GetValue в функции main.
Мой реальный случай на самом деле более сложный, поскольку код шаблона находится в библиотеке, на которую ссылаются. Там я получаю ошибку привязки, хотя я вижу, что функция экземпляра шаблона находится внутри библиотеки при проверке с помощью ‘nm’.
Как мне заставить этот тип создания экземпляра шаблона работать с GCC?
Комментарии:
1.
template<typename T> int GetValue(A value)
Подразумевается ли это специализацияtemplate<typename T> int GetValue(T value);
?2. Да, определение шаблона «template<имя_типа T> int GetValue(значение T)» на самом деле является определением интерфейса, тогда как специализация обеспечивается другими частями кода, которые более распространены. Сценарий использования заключается в том, что реализация может быть предоставлена и связана по мере необходимости, но интерфейс остается. Шаблонная версия GetValue фактически используется в шаблонном классе, поэтому тип A не известен, когда используется там.
Ответ №1:
При определении специализации вам необходимо удалить параметры типа … измените код с
template<typename T> int GetValue(A value)
{
return value.value;
}
Для
template<> int GetValue(A value)
{
return value.value;
}
И все будет работать так, как ожидалось
Комментарии:
1. И обратите внимание, что в этом конкретном примере вы могли бы также использовать простую перегрузку функции (вообще без шаблона).