Создание экземпляра шаблона в GCC отличается от Visual C

#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. И обратите внимание, что в этом конкретном примере вы могли бы также использовать простую перегрузку функции (вообще без шаблона).