-1

I've got two c++ templates. I want to have h and cpp files. It works with only one template but it doesn't work with two different templates. I receive this error from gcc:

../Temp1.cpp:16:17: error: definition of ‘Name::Temp1<T>::Temp1()’ is not in namespace enclosing ‘Name::Temp1<T>’ [-fpermissive]
../Temp1.cpp:22:18: error: definition of ‘Name::Temp1<T>::~Temp1()’ is not in namespace enclosing ‘Name::Temp1<T>’ [-fpermissive]
make: *** [Temp2.o] Error 1

Here the code for Temp1 header:

#ifndef TEMP1_H_
#define TEMP1_H_

namespace Name {

template<class T>
class Temp1 {
public:
    Temp1();
    virtual ~Temp1();
};

#include "Temp1.cpp"

} /* namespace Name */

#endif /* TEMP1_H_ */

Temp1 cpp:

#ifndef TEMP1_CPP_
#define TEMP1_CPP_

#include "Temp1.h"

namespace Name {

template<class T>
Temp1<T>::Temp1() {
    // TODO Auto-generated constructor stub

}

template<class T>
Temp1<T>::~Temp1() {
    // TODO Auto-generated destructor stub
}

} /* namespace Name */

#endif

Temp2 header:

#ifndef TEMP2_H_
#define TEMP2_H_

#include "Temp1.h"

namespace Name {

template<class T>
class Temp2: public Temp1<T> {
public:
    Temp2();
    virtual ~Temp2();
};

#include "Temp2.cpp"

} /* namespace Name */

#endif /* TEMP2_H_ */

Temp2 cpp:

#ifndef TEMP2_CPP_
#define TEMP2_CPP_

#include "Temp2.h"

namespace Name {

template<class T>
Temp2<T>::Temp2() {
    // TODO Auto-generated constructor stub

}

template<class T>
Temp2<T>::~Temp2() {
    // TODO Auto-generated destructor stub
}

} /* namespace Name */

#endif
greywolf82
  • 21,813
  • 18
  • 54
  • 108
  • Templates should be implemented where they are declared. –  Dec 27 '14 at 11:01
  • Templates in headers will go against what you know about writing headers. You'll either have to provide for each specialization you predict to handle or put it in the header, not the cpp. – ChiefTwoPencils Dec 27 '14 at 11:01
  • Don't `include` .cpp files in .h files. – Wojtek Surowka Dec 27 '14 at 11:03
  • 1
    I see that you're including your cpp files in your header files, which is kind of correct since they're template files, but they shouldn't be in cpp files at all, they should be declared directly in the header file, or in included tpp files if you prefer that. The important thing is that the template definitions are written directly in the headers. Also, your header guards are protecting you, but including everything everywhere is still confusing and is in this case causing problems. – keyser Dec 27 '14 at 11:03
  • 1
    @keyser changing cpp to tpp doesn't change anything – greywolf82 Dec 27 '14 at 11:05
  • 1
    @greywolf82 I know, that's not what I said. – keyser Dec 27 '14 at 11:06

1 Answers1

3

You included Temp1.cpp inside the namespace body in Temp1.h, and Temp1.cpp has a namespace Name too. Consider how it ends up looking like after preprocessing:

namespace Name {

template<class T>
class Temp1 {
public:
    Temp1();
    virtual ~Temp1();
};

namespace Name {

template<class T>
Temp1<T>::Temp1() {
    // TODO Auto-generated constructor stub

}

template<class T>
Temp1<T>::~Temp1() {
    // TODO Auto-generated destructor stub
}

} /* namespace Name */

} /* namespace Name */

In other words, you accidentally put the member function definitions in the namespace Name::Name, rather than the namespace Name.

As a side note, the usual convention is that you don't use the .cpp extension for files are intended to be included in other files rather than compiled separately.

T.C.
  • 133,968
  • 17
  • 288
  • 421