При компиляции выводиться ошибка, вот такая
c++ main.cpp vi.cpp -o l
vi.cpp:4:3: error: ‘template<class T> class vi’ used without template parameters
T vi::operator[](int idx)
^~
vi.cpp:4:25: error: ‘T operator[](int)’ must be a nonstatic member function
T vi::operator[](int idx)
Вот код.
main.cpp
#include <iostream>
#include "vi.h"
int main ()
{
vi<int> v;
int s = v[0];
std::cout << s << "\n";
}
vi.h
#include <vector>
template<typename T>
class vi {
std::vector<T> vr;
public:
T operator[](int idx);
};
vi.cpp
#include "vi.h"
template<typename T>
T vi::operator[](int idx)
{
return 1;
}
Шаблон - это не класс, шаблон - это не функция. Шаблон - это просто чертеж(паттерн, план), который будет использоваться компилятором для генерации семейства классов/функций.
Если компилятор генерирует функцию/класс из шаблона, он должен 'видеть' определения генерируемых им функций/методов класса.
Компилятор не собирает проект, т.е. он не видит связей между несколькими .cpp файлами. Это делает ваша IDE.
В вашем случае: в main.cpp будет создан экземпляр vi<int> и объявлен(не определен!) метод vi::operator[]. Он будет просто объявлен, т.к. в шаблоне вы однозначно указали компилятору: 'Только объяви!'(T operator[](int idx);). И это все не будет иметь никакого отношения к вашим определениям в vi.cpp.
Это все наводит на мысль, что лучше определять реализацию методов прямо в шаблоне класса, или в том же файле, где объявляется шаблон.
При крайней необходимости или огромном желании разделить интерфейс и реализацию, вы можете воспользоваться следующим подходом:
// vi.h
#include <vector>
template<typename T>
class vi {
std::vector<T> vr;
public:
T operator[](int idx);
};
#include "vi"
// ^^^^^^^^^^
// vi (файл без расширения)
// реализация из бывшего vi.cpp
template<typename T>
T vi<T>::operator[](int idx)
{
return 1;
}
Это позволит компилятору 'видеть' одновременно и объявление шаблона, и определение шаблонных методов
Вместо файла без расширения vi вы можете выбрать любое другое имя с любым расширением.
Одно замечание: ваша IDE может жаловаться на подобный код, но это абсолютно легальный подход. Вы можете выполнить компиляцию и линковку из командой строки при необходимости.
Templates definition and declaration. C++ FAQ
template<typename T>
T vi<T>::operator[](int idx)
{
return 1;
}
Сборка персонального компьютера от Artline: умный выбор для современных пользователей