Ошибка с использованием значений по умолчанию в конструкторе копирования шаблонного класса

У меня есть следующие шаблонные классы,

template <typename Real>
class Marker {

 typedef Wm5::Vector3<Real> Position ;
 typedef Wm5::Vector3<Real> Normal ;
 typedef Wm5::Vector3<Real> Color ;

 public:

  Marker(int id = -1, Position position = Wm5::Vector3<Real>::ZERO, Normal normal = Wm5::Vector3<Real>::ZERO, Color color = Wm5::Vector3<Real>::ZERO)
: id_(id), position_(position), normal_(normal), color_(color), cluster_(-1) {}

  ~Marker() {}

 private:

  int id_ ;
  Position position_ ;
  Normal normal_ ; 
  Color color_ ;
  int cluster_ ;

};


template <typename T> 
class MarkerSet {

    typedef Marker<T> MarkerT ;      
    typedef std::vector<MarkerT> MarkerVector ;

public:

    MarkerSet::MarkerSet(int id = -1, MarkerVector markers = MarkerVector()) 
   {id_ = id; markers_ = markers;}      

   MarkerSet::~MarkerSet() {}

private:

    int id_ ;   
    MarkerVector markers_ ;

} ;

Когда я пытаюсь создать объект MarkerSet с помощью

MarkerSet<double> markerSet ; 

Получение этой ошибки компоновщика,

error LNK2001: unresolved external symbol "public: __thiscall     MarkerSet<double>::MarkerSet<double>(int,class std::vector<class Marker<double>,class std::allocator<class Marker<double> > >)" (??0?$MarkerSet@N@@QAE@HV?$vector@V?$Marker@N@@V?$allocator@V?$Marker@N@@@std@@@std@@@Z)

Я был бы очень признателен, если бы кто-нибудь мог указать мне правильное направление в отношении того, что я сделал неправильно.

Редактировать:

Хорошо, я сузил его до чего-то довольно странного.

in .h

  MarkerSet(int id = -1, MarkerVector markers = MarkerVector()) 
{id_ = id; markers_ = markers;}    

хорошо строит

Вместо .h

 MarkerSet(int id = -1, MarkerVector markers = MarkerVector()) ;

в .cpp

 template <typename T>
 MarkerSet<T>::MarkerSet(int id, MarkerVector markers) {

  id_ = id ;
  markers_ = markers ;

}

Ошибки выводятся способом, описанным выше.

Есть предположения?


person oracle3001    schedule 13.03.2012    source источник
comment
Возможно ли, что у вас есть устаревший объектный файл, вокруг которого используется более старое определение MarkerSet? Попробуйте очистить или перестроить все в вашей среде IDE?   -  person aschepler    schedule 13.03.2012
comment
Да, я пробовал очистить и восстановить все.   -  person oracle3001    schedule 13.03.2012


Ответы (2)


Может попробовать использовать другой компилятор? Я попытался поиграть с ним, и следующее отлично работает для меня с gcc. Я исключил членов Wm5, так как у меня их нет. Вставка заголовка и cpp:

тест.ч

#include <vector>

template <typename Real>
class Marker {

 public:

  Marker(int id = -1,int _position=1)
    : id_(id), position(_position){}

  ~Marker() {}

 private:

  int id_ ;
  int position ;
  Real r;

};


template <typename T> 
class MarkerSet {

    typedef Marker<T> MarkerT ;      
    typedef std::vector<MarkerT> MarkerVector ;

public:

    MarkerSet(int id = -1, MarkerVector markers = MarkerVector()) 
      {id_ = id; markers_ = markers;std::cout<<"Called"<<std::endl;}      

   ~MarkerSet() {}

private:

    int id_ ;   
    MarkerVector markers_ ;

} ;

test.cpp

#include <iostream>
#include <vector>
#include "test.h"

using namespace std;


int main(int argc, const char **argv) {
  cout<<"Hello"<<endl;
  MarkerSet<double> ms;
  return -1;

}

команда:

bash$ ./test
Hello
Called
bash$ 

Определение класса шаблона должно быть в заголовке:

Почему определения шаблонов C++ должны быть в заголовок?

person Sid    schedule 13.03.2012
comment
Хорошо, я получил его для сборки на моей машине VS2010 .... Я понятия не имею, чем отличается этот MarkerSet (int id = -1, MarkerVector markers = MarkerVector()) {id_ = id; markers_ = markers;std::cout‹‹Called‹‹std::endl;} и MarkerSet(int id = -1, MarkerVector markers = MarkerVector()) ; в .h и шаблон ‹typename T› MarkerSet‹T›::MarkerSet(int id, маркеры MarkerVector) {id_ = id ; markers_ = маркеры ;} в файлах .cpp - person oracle3001; 14.03.2012
comment
Я не включаю MarkerSet‹T›:: перед именами функций. Поскольку определение находится внутри класса, вам не нужно уточнять имя класса. gcc на самом деле жаловался на это. Также все определения находятся в заголовке, так как это классы-шаблоны. - person Sid; 14.03.2012
comment
Я понимаю. См. редактирование выше как более четкое объяснение проблемы, которая все еще существует. - person oracle3001; 14.03.2012
comment
Вы не можете помещать определения классов шаблонов в файлы .cpp. Вам нужно поместить их в заголовки, чтобы они были доступны во время компиляции. Это должно быть вашей проблемой. Вот, прочитайте это: stackoverflow.com/questions/5180357/ - person Sid; 14.03.2012
comment
Готово... Все еще разбираюсь с этим переполнением стека :-) - person oracle3001; 14.03.2012

Может ли быть так, что вы не #include делаете тело конструктора, чтобы компоновщик не генерировал требуемый код для MarkerSet<double>::MarkerSet<double>(int,class std::vector<class Marker<double>,class std::allocator<class Marker<double> > >)"?

person gluk47    schedule 13.03.2012
comment
Только что попробовал изменить дополнительную квалификацию и все еще получаю ту же ошибку. Использование VS2010 в качестве компилятора. - person oracle3001; 13.03.2012
comment
Я не совсем понимаю, что вы имеете в виду под не #include фактическим телом конструктора. - person oracle3001; 13.03.2012
comment
К сожалению, я имел в виду именно то, что предложил Сид, либо перенести тело конструктора в заголовок, либо #include cpp-файл с телом, а не только включить заголовок с прототипом. Мой плохой, я должен был уточнить это. - person gluk47; 15.03.2012