Как переслать объявление шаблона класса в пространстве имен std? - PullRequest
128 голосов
/ 07 октября 2010
#ifndef __TEST__
#define __TEST__

namespace std
{
    template<typename T>
    class list;
}

template<typename T>
void Pop(std::list<T> * l)
{
    while(!l->empty())
        l->pop();
}

#endif

и использовал эту функцию в моей главной.Я получаю ошибки.Конечно, я знаю, что есть больше параметров шаблона для std::list (думаю, распределитель).Но это не относится к делу.Нужно ли мне знать полное объявление шаблона класса шаблона, чтобы иметь возможность пересылать его?

РЕДАКТИРОВАТЬ: раньше я не использовал указатель - это была ссылкаЯ попробую это с указателем.

Ответы [ 4 ]

138 голосов
/ 07 октября 2010

Проблема не в том, что вы не можете заранее объявить класс шаблона. Да, вам нужно знать все параметры шаблона и их значения по умолчанию , чтобы иметь возможность правильно объявить его вперед:

namespace std {
  template<class T, class Allocator = std::allocator<T>>
  class list;
}

Но даже сделать такое предварительное объявление в namespace std прямо запрещено стандартом: только вещь, которую вы можете поместить в std, является шаблоном специализация , обычно std::less для пользовательского типа. При необходимости кто-то другой может процитировать соответствующий текст.

Просто #include <list> и не беспокойтесь об этом.

Кстати, любое имя, содержащее двойное подчеркивание, зарезервировано для использования реализацией, поэтому вы должны использовать что-то вроде TEST_H вместо __TEST__. Он не будет генерировать предупреждение или ошибку, но если в вашей программе есть конфликт с идентификатором, определяемым реализацией, то не гарантируется, что он будет правильно скомпилирован или запущен: это плохо сформировано . Также запрещены имена, начинающиеся с подчеркивания, за которым следует, помимо прочего, заглавная буква. В общем, не начинайте с подчеркивания, если не знаете, с какой магией вы имеете дело.

20 голосов
/ 31 августа 2012

Я решил эту проблему.

Я реализовывал слой OSI (окно слайдера, уровень 2) для симуляции сети в C ++ (Eclipse Juno). У меня были кадры (шаблон <class T>) и его состояния (шаблон состояния, предварительное объявление).

Решение выглядит следующим образом:

В файле *.cpp вы должны включить отправляемый вами заголовочный файл, т.е.

ifndef STATE_H_
#define STATE_H_
#include <stdlib.h>
#include "Frame.h"

template <class T>
class LinkFrame;

using namespace std;

template <class T>
class State {

  protected:
    LinkFrame<int> *myFrame;

}

Его cpp:

#include "State.h"
#include "Frame.h"
#include  "LinkFrame.h"

template <class T>
bool State<T>::replace(Frame<T> *f){

И ... еще один класс.

10 голосов
/ 07 октября 2010

В предварительном объявлении должен быть указан полный список аргументов шаблона.

0 голосов
/ 13 апреля 2013

есть ограниченная альтернатива, которую вы можете использовать

Заголовок:

class std_int_vector;

class A{
    std_int_vector* vector;
public:
    A();
    virtual ~A();
};

касты:

#include "header.h"
#include <vector>
class std_int_vector: public std::vectror<int> {}

A::A() : vector(new std_int_vector()) {}
[...]

не тестировалось в реальных программах, так что ожидайте, что оно будет несовершенным.

...