На данный вопрос уже ответили:
Выдает вот такую ошибку. Объявления вроде есть, а в коде их не видит. makefile и код в спойлерах ниже
main.o: In function `main':
main.cpp:(.text+0x2b): undefined reference to
`containers::vector<int>::push_back(int&&)'
main.cpp:(.text+0x45): undefined reference to
`containers::vector<int>::push_back(int&&)'
main.o: In function `void outarr<int>(containers::vector<int>&)':
main.cpp (.text._Z6outarrIiEvRN10containers6vectorIT_EE
[_Z6outarrIiEvRN10containers6vectorIT_EE]+0x22):
undefined reference to `containers::vector<int>::size()'
main.cpp:
(.text._Z6outarrIiEvRN10containers6vectorIT_EE
[_Z6outarrIiEvRN10containers6vectorIT_EE]+0x3d):
undefined reference to `containers::vector<int>::operator[](int)'
makefile:
all: vector
vector: main.o vector.o
g++ main.o vector.o -o vector
main.o: main.cpp
g++ -c main.cpp
vector.o: vector.cpp
g++ -c vector.cpp
clear:
rm -rf *.o
main.cpp
#include "vector.h"
#include <iostream>
using namespace containers;
template<class T>
void outarr(vector<T>& v) {
for(int i = 0; i < v.size(); ++i)
std::cout << v[i] << "\t";
}
int main() {
vector<int> test;
test.push_back(0);
test.push_back(3);
outarr<int>(test);
return 0;
}
vector.h
#ifndef CONTAINER_VECTOR
#define CONTAINER_VECTOR
#include <cstddef>
#include <initializer_list>
namespace containers {
template<class T>
class vector {
private:
T* array;
std::size_t vector_size = 0;
std::size_t vector_capacity;
public:
vector() {}
vector(std::initializer_list<T> init);
vector(std::size_t size);
vector(vector& other);
~vector() { delete[] array; }
std::size_t size();
std::size_t capacity();
void reserve(std::size_t size);
void push_back(const T& value);
void push_back(T&& value);
void insert(std::size_t pos, const T& value);
void insert(std::size_t pos, T&& value);
T& pop_back();
void clear();
void erease(std::size_t pos);
void erease(std::size_t from, std::size_t to);
T& operator[](int index);
//T& operator=(T& other);
};
}
#endif
vector.cpp
#include "vector.h"
#define tplate template<class T>
namespace containers {
tplate
vector<T>::vector(std::initializer_list<T> init) {
vector_size = init.size();
array = new T[vector_size];
for(int i = 0; i < vector_size; ++i)
array[i] = init[i];
}
tplate
vector<T>::vector(std::size_t size) {
vector_size = size;
array = new T[vector_size];
}
tplate
vector<T>::vector(vector& other) {
vector_size = other.vector_size;
array = new T[vector_size];
for(int i = 0; i < vector_size; ++i)
array[i] = other[i];
}
tplate
std::size_t vector<T>::size() { return vector_size; }
tplate
std::size_t vector<T>::capacity() { return vector_capacity; }
tplate
void vector<T>::reserve(std::size_t size) {
T* newarr = new T[size];
for(int i = 0; i < vector_size; ++i)
newarr[i] = array[i];
vector_size = size;
delete[] array;
array = newarr;
}
tplate
void vector<T>::push_back(const T& value) {
if(vector_size <= vector_capacity)
reserve(++vector_size);
array[vector_capacity] = value;
++vector_capacity;
}
tplate
void vector<T>::push_back(T&& value) {
if(vector_size <= vector_capacity)
reserve(++vector_size);
T* newel = value;
array[vector_capacity] = *newel;
++vector_capacity;
}
tplate
void vector<T>::insert(std::size_t pos, const T& value) {
if(pos > vector_capacity) {
vector_size = pos;
vector_capacity = pos;
reserve(vector_size);
}
for(int i = vector_size; i > pos+1; --i)
array[i] = array[i-1];
array[pos] = value;
}
tplate
T& vector<T>::operator[](int index) {
return array[index];
}
} // namespace containers
#undef tplate
Для начала избавтись от
#define tplate template<class T>
А так, тело шаблонных функций/классов должно быть в .h файле, дя красоты его можно вынести в отдельный .inl файл и подключить снизу в .h файле.
Либо, сделать явную инстанциацию шаблоного класса для определенного типа в .cpp файле, в том файле где "видно" тела шаблонных методов
template class vector<int>;
Стандартная ошибка. Реализация шаблона должна быть доступна, без этого не происходит его инстанцирование. Так что переместите код из vector.cpp
в vector.h
- иначе происходит следующее: при компиляции main.cpp
инстанцирования нет (как инстанцировать то, чего незнаешь?), а в vector.cpp
опять же инстанцирования нет - потому что раз класс не используется - зачем его инстанцировать?
Можно, конечно, явно указать в vector.cpp
на необходимость инстанцирования для того или иного типа, но это способ не лучший - вдруг понадобится вектор еще какого-то типа?
И еще, на всякий случай - надеюсь, вы знаете, что в
void push_back(T&& value);
value
- универсальная ссылка, а не r-ссылка?
Судя по
T* newel = value;
array[vector_capacity] = *newel;
я вообще не пойму, чем вы ее считаете... Указателем на T
?
И последнее - вот такие вещи
#define tplate template<class T>
отнюдь не способствуют пониманию кода, особенно если их становится много. Экономия, не стоящая того. Да и тогда уж хотя бы назовите TPLATE
- чтоб хотя бы сразу видеть, что это макрос.
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Виртуальный выделенный сервер (VDS) становится отличным выбором
Данный код считает максимальную компоненту связностиКак найти их количество? Например,