简体   繁体   中英

C++ Templates Declaration Order

I am trying to compile a minimal example which instantiates a template class. The example compiles fine when a certain order of declarations is kept, but fails otherwise.

temp.h:

#include <iostream> 
template <bool display>
class test {
    public:
    void sayHi(); 
};

temp.cpp:

#include "temp.h"
template <bool display>
void  test<display>::sayHi () {
    if (display) std::cout << "Hi";
}

main.cpp:

#include <iostream>
#include "temp.h"
int main () {
    test<true> myobject;
    myobject.sayHi();
    return 0;
}

This is the standard of how to include classes. In GCC 4.4.6, this fails with the error main.cpp:(.text+0x3a): undefined reference to `test::sayHi()'

However, the example compiles when I do a #include "temp.cpp" instead of #include "temp.h" in main.cpp file, so that the compiler reads the class declaration in temp.h first, then sees the content of temp.cpp and only afterwards the content of main.cpp.

When I use non-template classes, it works fine to include just .h files in main.cpp -- what is going wrong here? Note that the temp.cpp is included in my Makefile, so it definitely should not be forgotten by the compiler. Thanks for any help.

See the C++ FAQ Lite entry [35.12] Why can't I separate the definition of my templates class from its declaration and put it inside a .cpp file? .

The definition (aka body) of the sayHi() method must be in the temp.h header, or in another included file; the full code is needed when you instantiate test<true> .

With templates, both declaration and definition must be in the same file. You can do this by either putting all your code in one file (and making the function definitions inline or not, it's up to you), or making the declaration and definitions seperate, but including the definitions file at the bottom of the .h file .

So it would be

tmp.h:

#include <iostream> 
template <bool display>
class test {
    public:
    void sayHi(); 
};

#include "tmp.cpp"

and tmp.cpp and main.cpp remain the same (but you don't give tmp.cpp to the compiler to compile since it's included by tmp.h).

Many people name the files that have template function definitions in them with a .template extension instead of .cpp extension (it lets you know it's not to be compiled, plus it looks less weird than including a .cpp file), but you don't have to.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM