0

/***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

Lohitaksh Trehan
  • 304
  • 2
  • 12
  • How do you build your project? Show us a precise command – alexeykuzmin0 Apr 11 '17 at 08:53
  • 2
    g++ main.cpp is enough, because you dont compile .h files – Lohitaksh Trehan Apr 11 '17 at 08:54
  • when i used btack.cpp i did g++ btack.cpp main.cpp – Lohitaksh Trehan Apr 11 '17 at 08:55
  • ask me if you want more specifications – Lohitaksh Trehan Apr 11 '17 at 08:56
  • What exact compilation commands have you run? What actual diagnostics did you get? Please edit your question to improve it. – Basile Starynkevitch Apr 11 '17 at 08:59
  • 2
    Possible duplicate of [Why can templates only be implemented in the header file?](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Richard Critten Apr 11 '17 at 09:01
  • @RichardCritten i have read that post, the solution that you want to state here that is : – Lohitaksh Trehan Apr 11 '17 at 09:09
  • "Another solution is to keep the implementation separated, and explicitly instantiate all the template instances" -----------is a bad solutionn as may be i will be using object of a class defined by me, this will hurt the portability of header file – Lohitaksh Trehan Apr 11 '17 at 09:10
  • @BasileStarynkevitch the commands: g++ btack.cpp main.cpp (where i get linkage errors) , and where i dont have a seprate btack.cpp i do :g++ main.cpp (it works well) – Lohitaksh Trehan Apr 11 '17 at 09:13
  • 1
    I think you didn't really get the meaning of *explicitly instantiate all the template instances*. Please read about it here: [How do I explicitly instantiate a template function?](http://stackoverflow.com/questions/4933056/how-do-i-explicitly-instantiate-a-template-function/4933205#4933205) – dtell Apr 11 '17 at 09:13
  • @LohitakshTrehan: please **edit your question**, don't add comments here. – Basile Starynkevitch Apr 11 '17 at 09:16
  • i get it , but 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 @datell – Lohitaksh Trehan Apr 11 '17 at 09:16
  • @BasileStarynkevitch sorry, noob mistake – Lohitaksh Trehan Apr 11 '17 at 09:17
  • 3
    As an aside, `using namespace std` in a header is a bit of a bad smell, any other module which includes your header will automagically be using namespace std, and could lead to name conflicts or incorrect functionality. – Colin Apr 11 '17 at 09:26
  • it was a small implementation, otherwise i would have use "std::" instead, thanks for pointing out @Colin__s – Lohitaksh Trehan Apr 11 '17 at 09:29
  • 1
    Instead of mentioning my answer in your question (which is very uncommon) you can upvote or accept it. See [Somone answers](http://stackoverflow.com/help/someone-answers) for further information. – dtell Apr 11 '17 at 09:31
  • comments are good, no answer, and i will aceept it, about upvote(i dont have a reputation, but i will click anyways ) @datell , hope you upvote my question too – Lohitaksh Trehan Apr 11 '17 at 09:34

4 Answers4

1

Since you are using a template class you don't need any .cpp file for an implementation of it.

So you got two files: main.cpp and btack.h. Main contains #include "btack.h".

You compile it with g++ main.cpp.

dtell
  • 2,488
  • 1
  • 14
  • 29
  • wont that harm the basic idea of abstractness i.e. seprating code and declaration. – Lohitaksh Trehan Apr 11 '17 at 09:15
  • C++14 does not really permit abstract templates... In some sense, they need to be "concrete" (implemented in header files) – Basile Starynkevitch Apr 11 '17 at 09:17
  • @datell: Wrong advice: should be compiled with `g++ -Wall -g main.cpp` since both `-Wall`(for all warnings) & `-g` (for debug info) are needed – Basile Starynkevitch Apr 11 '17 at 09:18
  • 1
    The reason for this is the usage of templates. Imagine it like this: If you would separate your `btack.h` into `back.h` (containing signatures) and `btack.cpp` (containing implementations) and you would compile everything the compiler would try to compile `btack.cpp` without knowlege of `main.cpp`. What shoudl he do with the generic type `T`? He don't now how it is going to used concretly in `main.cpp`. Therefore the header must either contain the template implementationen or you explicitly instantiate all the template instances. – dtell Apr 11 '17 at 09:19
  • @BasileStarynkevitch so there is no way out? – Lohitaksh Trehan Apr 11 '17 at 09:20
  • @datell you said right about diferent compilations, i read that yesterday – Lohitaksh Trehan Apr 11 '17 at 09:21
  • @LohitakshTrehan: no, there is no practical way in C++14 .... Look into the source code of `` in practice, or compile some file using standard C++ containers with `g++ -C -E -H` to get the preprocessed form, then study it... Look into module proposal for future C++ standards. – Basile Starynkevitch Apr 11 '17 at 09:21
  • @BasileStarynkevitch I gave him a small working example not an advice for final build or testing rules. But you are right, one should always use at least some additional compiler flags. – dtell Apr 11 '17 at 09:22
  • Thanks @datell i will study some more, because i really need to know about these compiler flags – Lohitaksh Trehan Apr 11 '17 at 09:25
  • Thanks @BasileStarynkevitch i will study some more, because i really need to know about these compiler flag – Lohitaksh Trehan Apr 11 '17 at 09:25
1

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.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
0

three separated files

btack.cpp with the cpp code for btack btack.h the header file main.cpp

in main.cpp ; on first line just write

 #include "btack.h"

if btack is in the same directory; if it's not, write the path of the file

then compile main.cpp and btack.cpp (don't forget to also #include "btack.h" in btack.cpp)

RomMer
  • 909
  • 1
  • 8
  • 19
  • no its not working, i am using a template class. its giving errors, previously it was some "export" keyword, but new c++ has deleted its use – Lohitaksh Trehan Apr 11 '17 at 08:59
  • i can compile your code on ubuntu 16.10 with g++ 6.2 @LohitakshTrehan – RomMer Apr 11 '17 at 09:01
  • i gave you the code which was compiling i.e. both declaration and defination in .h file, if you seprate the defination in btack.cpp file, then it gives linking error – Lohitaksh Trehan Apr 11 '17 at 09:08
0
// stack node structure
struct Node {
    char data;
    struct Node* next;
};
struct Node* initiStack(void);
int isEmpty(struct Node** top);
// push function
void push(struct Node** top, int data);

// pop function
int pop(struct Node** top);
int peek(struct Node** top_re);
int size(char expn[]);
Cristian
  • 654
  • 1
  • 13
  • 30