Вообще говоря, определения шаблонов также должны быть в заголовочном файле.Исключением является случай, когда вы явно создаете экземпляр или используете явные специализации, чего вы не делаете.
Один из способов решить эту проблему - переместить содержимое genericStackImpl.c++
в конец его заголовка.файл.
Причина этого в том, что функции шаблонов не являются реальными функциями, они просто шаблоны.Шаблон используется (создается) для создания актуальных функций, и это то, на что вы ссылаетесь.
В genericStackImpl.c++
нет функций.Функции создаются только после их использования, то есть когда компилятор впервые видит sc.push
и sc.pop
.К сожалению, когда driver.c++
пытается создать эти функции, он не может найти тела шаблона - они скрыты в genericStackImpl.c++
!Вместо этого он просто компилирует ссылку на эти функции, надеясь, что их создаст какой-то другой файл.
Наконец, когда дело доходит до времени ссылки, компоновщик нигде не может найти функцию, поэтому он дает вамошибка.
Другим способом решения этой проблемы было бы явное создание экземпляров этих функций самостоятельно в genericStackImpl.c++
, то есть
template class Stack<char>;
Это создаст функции, и компоновщик найдет их.
Проблема этого подхода в том, что он требует от вас заранее знать, какие типы вы собираетесь использовать в стеке, поэтому большинство людей просто помещают определения шаблонов в заголовочный файл.