开发者

explicit instantiation of parameterized template methods

开发者 https://www.devze.com 2023-01-25 16:24 出处:网络
I\'ve two different template classes, one of them using as parameter an object of the another template class. i\'m getting an error message:

I've two different template classes, one of them using as parameter an object of the another template class. i'm getting an error message: collect2: ld returned 1 exit status make: * [main] Error 1

I'm working with explicit instantiation of templates and I found some related posts but they were mostly related to instantiations of one single template class. In my case, I've 3 files per class (.h, .cpp, .inc following http://www.parashift.com/c++-faq/templates.html#faq-35.13 suggestion).

foo.h

 #ifndef FOO_H
 #define FOO_H
 template < class S >
 class Foo{
    public: ...
    private: ... 
 };
 #endif

foo.cpp

  ...
  template < class S >
  Foo<S>::Foo(){ .... }
  ...
  #include "foo.inc"

foo.inc

 template class Foo<int>;
 template class Foo<float>;
开发者_Python百科

bar.h

 #ifndef BAR_H
 #define BAR_H
 #include <mylib.h>
 template < class T >
 class Bar{
    public: ...
           template <class S>
           void doSomething(Foo<S>*);
    private: ... 
 };
 #endif

bar.cpp

  ....
  template <class T> template <class S>
  void Bar<T>::doSomething(Foo<S>*p){
      ....
  }
  .....
  #include "bar.inc"

bar.inc

 template class Bar<int>;
 template class Bar<float>;
 template void Bar<int>::doSomething(Foo<int>*);
 template void Bar<float>::doSomething(Foo<float>*);

mylib.h

 #include <foo.h>
 #include <bar.h>

main.cpp

#include <mylib.h>
#include <common.h>

int main(){
    Foo<float> * pFoo = NULL;
    pFoo = new Foo<float>();

    Bar<float> * pBar = NULL;
    pBar = new Bar<float>();
    pBar->doSomething(pFoo);

    delete pFoo;
    delete pBar;

    return (0);
}

Does anybody see any problem/bug on the way I'm instantiating the objects? The complete error message is (I changed the name of the classes and simplified the code so as to be more understandable):

 g++ -O3 -Wall main.cpp -o ../bin/main -I../inc -L../lib -lmylib -lm
 /tmp/cciJHsKr.o: In function `main':
 main.cpp:(.text+0x19f): undefined reference to `void Bar<float>::doSomething<float>(Foo<float>*)'
 collect2: ld returned 1 exit status
 make: *** [main] Error 1

Note that, I compile both foo.cpp and bar.cpp separately, since I'm generating a library.

 // Makefile for foo.cpp & bar.cpp
 INC=./inc
 SRC=./src
 LIB=./lib
 OBJ=./obj

 CC=g++
 CFLAGS=-O3 -Wall

 mylib: $(LIB)/mylib.a
      echo "mylib was created!..."

 $(LIB)/mylib.a: \
 $(OBJ)/bar.o \
 $(OBJ)/foo.o 
ar csr $(LIB)/mylib.a \
 $(OBJ)/bar.o \
 $(OBJ)/foo.o \


 $(OBJ)/bar.o: $(SRC)/bar.cpp
      $(CC) -c $(CFLAGS) $(SRC)/bar.cpp -I$(INC) \
      -o $(OBJ)/bar.o


I solve the problem!

bar.h

#ifndef BAR_H
#define BAR_H
#include <mylib.h>
template < class T >
class Bar{
    public: ...
       template <class fooType>
       void doSomething(fooType*);
    private: ... 
};
#endif

bar.cpp

#include <bar.h>
#include <foo.h>
...
...
template <class T> template <class fooType>
void Bar<T>::doSomething(fooType*p){
  ....
}
.....
#include "bar.inc"

bar.inc

#include <foo.h>

template class Bar<int>;
template class Bar<float>;
template void Bar<int>::doSomething(Foo<int>*);
template void Bar<float>::doSomething(Foo<float>*);


I haven't got a environment with GCC setup at the moment, so I'm flying blind here.

There seems to be a few problems with your code (as my mental compiler sees it).

  1. In bar.cpp you haven't scoped the doSomething() function. Given it has been declared in a separate header you need Bar::doSomething(). Given Bar is templated you also need to provide a binding i.e. Bar<T>::doSomething().

  2. In bar.cpp the template bindings appear to be the wrong way around (they can be arbitrary in your example, but), for clarify I would change them around so that it is the following: template <class T> template <class S> void Bar<T>::doSomething(Foo<S>*p){ ... }

  3. Finally the main() has a problem, in that you are not creating a Foo object on the heap - I think the compiler should catch this (assigning Foo to Foo*). I guess you've just missed the new keyword out. pFoo = new Foo<float>();

0

精彩评论

暂无评论...
验证码 换一张
取 消