В вашем комментарии указано «в файле реализации» для шаблона, что, вероятно, является причиной вашей проблемы. Объявления шаблонов функций (например, T operator+(const T&, const&);
объявляют символы, которые должны быть связаны, но для этого требуется создание этого шаблона где-то.
Простое определение функции template
в источнике файл на самом деле не создает экземпляр кода - он требует либо конкретных экземпляров каждого типа, с которым требуется связать явно, либо чтобы определение шаблона функции было видимым из того места, которое намеревается его вызвать (см. этот ответ для более подробной информации).
Во многих случаях лучше определить шаблон функции в файле заголовка, чтобы любой вызывающий шаблон мог создавать экземпляры функций без необходимости связывания с существующим создание экземпляра в другом месте.
Тем не менее ...
Возможно, вы захотите пересмотреть свой текущий подход. Ваш шаблон operator+
не ограничивает тип T
можно рассматривать, что приведет к тому, что operator+(const T&, const T&)
будет жизнеспособной перегрузкой для любого * Тип 1022 * T
, который еще не имеет operator+
, при условии, что объявление отображается во время разрешения перегрузки. Это может привести к другим странным ошибкам компилятора / компоновщика.
Существует несколько способов решения проблемы ограничения типа; вероятно, самым простым было бы использовать SFINAE, чтобы ограничить его, проверив, что T
является производным от Base
.
Например:
/// This is in the class header file
class Base
{
// Declare all the base storage and methods ...
public:
template<class T, class>
friend T operator+(const T& lhs, const T& rhs);
// .... other stuff in here.
}
// Note: In the same header!
// This only enables + if 'T' derives from 'Base'
template <typename T, typename = std::enable_if_t<std::is_base_of<Base,T>::value>>
T operator+(const T& lhs, const T& rhs)
{
return T(lhs->m_1 + rhs->m_1, lhs->m_2);
}