@pixik

Как написать интерфейс и реализацию шаблонного класса в c++?

Товарищи, тоброго времени суток!
Сегодня довольно много времени потратил, и так и не понял, как это можно сделать.
Хочу разобраться, как писать раздельно (интерфейс и реализацию) шаблонных классов в c++.

К примеру, на основе std queue и mutex хочу сделать блокирующую очередь, но я не знаю, какими объектами мне придётся пользоваться в разработке.
Я объявляю интерфейс:
#ifndef QUEUE_BLOCK_T_HPP
#define QUEUE_BLOCK_T_HPP

#include <queue>
#include <mutex>

template <class T>
class block_queue{

public:
  block_queue(int = 100); // default size
  ~block_queue();
  void push(const T&);
private:
  std::mutex lock;
  std::queue<T> q;
  int max_size;
};
#endif

И реализацию:
#include "queue_block_t.hpp"

template <class T>
block_queue<T>::block_queue(int max_size_) : max_size(max_size_){}

template <class T>
block_queue<T>::~block_queue(){}

template <class T>
void block_queue<T>::push(const T& elem){
  lock.lock();
  q.push(elem); 
  lock.unlock();
}

Использую, к примеру, так:
#include "queue_block_t.hpp"

int main(int argc, char **argv) {
  block_queue<int> q(500);
  q.push(10);
  return 0;
}

В итоге получаю:
main.cpp:7: undefined reference to `block_queue<int>::block_queue(int)'
main.cpp:8: undefined reference to `block_queue<int>::push(int const&)'
main.cpp:7: undefined reference to `block_queue<int>::~block_queue()'
main.cpp:7: undefined reference to `block_queue<int>::~block_queue()'

Почему эти функции необъявлены?

Так работает:
#ifndef QUEUE_BLOCK_T_HPP
#define QUEUE_BLOCK_T_HPP

#include <iostream>
#include <queue>
#include <mutex>

template <class T>
class block_queue{

public:
  block_queue(int max_size__ = 100) : max_size(max_size__) { }
  ~block_queue(){ }
  void push(const T& elem){
     lock.lock();
     q.push(elem);
     lock.unlock();
  }
private:
  std::mutex lock;
  std::queue<T> q;
  int max_size;
};
#endif


Всем спасибо!
  • Вопрос задан
  • 996 просмотров
Решения вопроса 3
LittleFatNinja
@LittleFatNinja
горе девелопер, любитель лютой садомии
нельзя разделить хедер и реализацию шаблонного класса, это невозможно
Ответ написан
Реализацию тоже в hpp.
Для каждого параметра T генерируется своя функция, а потому их потенциально бесконечно много, поэтому они должны быть доступны в исходном коде, а не линковаться отдельно.
Конечно, можно явно инстанцировать для нужных типов, но в вашем случае ни к чему.
Ответ написан
Комментировать
tsarevfs
@tsarevfs Куратор тега C++
C++ developer
https://toster.ru/answer?answer_id=652931 там в комментариях немного о том, почему так.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы