шаблонная специализация на C

#c #templates #instantiation #specialization

#c #шаблоны #создание экземпляра #специализация

Вопрос:

Я пытался разобраться в специализации шаблонов. Почему это генерирует ошибку ( specialization of 'T foo(T, T) [with T = int]' after instantiation )

 template <class T> T foo(T a, T b);

int main()
{
    int x=34, y=54;
    cout<<foo(x, y);
}

template <class T> T foo(T a, T b)
{
    return a b;
}

template <> int foo<int>(int a, int b)
{
    cout<<"int specialization";
}
  

Комментарии:

1. Просто переместите определения перед main .

2. Сижу под дождем, читаю вопрос со своего телефона Android, но не могу. отвечать вовремя БОЛЬНО

3. @JohannesSchaub-litb ты зависим!! обратитесь за помощью 😉

Ответ №1:

Стандарт требует, чтобы все определения шаблонов были известны во время создания экземпляра и чтобы каждая единица перевода видела одно и то же определение. В противном случае ваша программа будет неправильно сформирована (и фактически диагностика не требуется).

(Чтобы решить эту проблему, просто поместите все определения шаблонов в начало программы.)

Помните, что шаблонные функции — это не функции, а просто шаблоны. Думайте о них как об инструменте для генерации кода.

Ответ №2:

Явно специализированная шаблонная функция foo() должна быть видна до того, как ее можно будет вызвать / создать экземпляр.

Фактически, приведенное выше правило применимо ко всем функциям шаблона.

Решение:
Переместите специализацию шаблона для foo() перед своим main() .

Следующее должно работать просто отлично:

 template <class T> T foo(T a, T b);

/*Should be visible before instantiation*/
template <> int foo<int>(int a, int b)
{
    cout<<"int specialization";
}

int main()
{
    int x=34, y=54;
    cout<<foo(x, y);
}

template <class T> T foo(T a, T b)
{
    return a b;
}
  

Ответ №3:

Не делайте этого.

Что сказал Херб Саттер:

Если вы пишете базовый шаблон функции, предпочтите записать его как единый шаблон функции, который никогда не должен быть специализированным или перегруженным, а затем полностью реализовать шаблон функции как простую передачу доступа к шаблону класса, содержащему статическую функцию с той же сигнатурой.

Смотрите:http://www.gotw.ca/publications/mill17.htm