Search code examples
c++templatesheader-filespreprocessor

How to include a header file in c++?


/***You willl find good information in the answer selected and comments of post by @datell*****/

/**** Also there is something related to use off "modules" and "inline before template" (i am asking on template classes and not template functions, both are different) in c++, that if its related, i cant relate in reality(i am a noob)*****/

i am asking how can i include a header file in my main.cpp, i have implemented basic stack operations in it ; main.cpp btack.h and btack.cpp. Compiler is giving a long list of linkage errors(works fine if i give declaration and defination in btack.h, ofcourse i dont want to do that for modularity). its a temmplate class. i will provide the code which runs, that is without btack.cpp

main.cpp

#include <iostream>
using namespace std;
#include "btack.h"
int main() {
    char a;
    int z;
    //std::cout << "Hello, World!\n";
    btack <int> b(3);
    btack <char> c(3);
    b.push(4);
    b.push(5);

btack.h

#ifndef btack_h
#define btack_h
#include <iostream>
using namespace std;
template <typename s> class btack
{
    int TOS,size;
    s *ptr;
public:
    btack(int );
    ~btack();
    void push(s ob);
    s pop();

};

template <typename s> btack<s>::btack(int i)
{
    ptr = (s*)malloc(i*sizeof(s));
    TOS=0;
    size=i;
}

template <typename s> void btack<s>::push(s ob)
{
    if(TOS>=size)
    {
        cout<<"stack is full"<<endl;
        return;
    }
    ptr[TOS]=ob;
    TOS++;
}

template <typename s> s btack<s>::pop()
{
    if(TOS<=0)
    {
        cout<<"stack is empty"<<endl;
        return ((s) 0);
    }
    TOS--;
    return ptr[TOS];
}
template <typename s> btack<s>::~btack()
{free(ptr);}

#endif /* btack_h */

so basically i was going through so many internet posts and i found that you have to use "Export" keyword, but that word is no longer used, i was unable to find a proper guide on this topic. NEw c++ standards please. A guide how i can learn this thing from scratch. Please you mighty coders, a guiding link will help.

Update******** For all those saying about explicitly declaring data types at end of header: suppose it is a STL implementation of stack.h, you dont instantiate explicitly the various types of data types you want to use, it automatically do that


points of worth:

C++14 does not really permit abstract templates... In some sense, they need to be "concrete" (implemented in header files) – Basile Starynkevitch


Solution

  • In practice, a C++14 compiler needs to know for every aggregate type (in particular instantiated template classes) its size, alignment, vtable (if any) and sequence of fields -with their type and alignment-.

    Hence, templates are practically not abstract types, even if programmers should view them that way.

    Therefore, standard containers headers (like <vector>, <map> etc...) are generally including a lot of internal stuff defining the internal implementation of the template, and all the template member functions are inlined.

    In practice, a standard header like <vector> is expanded to a lot of stuff (about ten thousand lines of C++ on my GCC 6 compiler on Linux).

    Try the following command (it is preprocessing) with a simple file mytest.cc having #include <vector>:

     g++ -C -E -H -Wall mytest.cc > mytest.ii
    

    The -H option shows all the internal included files. The -C -E is asking for preprocessed form with comments into mytest.ii. Then look with an editor (or a pager) into the generated mytest.ii; it would be quite big.

    And that is why C++ compilation is often slow.

    Modules are a future feature of C++ which could help. See this question.