3

there are many solutions to this question bot nothing answers my case.

I am using VS 2008.I am tring to create a map using Binary search tree

#ifndef _map_h
#define _map_h


#include<string>
using namespace std;

template <typename ValType>
class Map
{
    public:
        Map();
        ~Map();
        ValType getvalue(string key);
        void add(string key,ValType value);

    private:
        struct node{
            string key;
            ValType value;
            node *right;
            node *left;
        };
        node *root;

        node *treeSearch(string key,node *t);

        void treeEnter(string key,ValType value,node *&t);
};
#include"map.cpp"

#endif

map.cpp

#include<string>
#include<iostream>
#include"map.h"
using namespace std;

template <typename ValType>
Map<ValType>::Map(){
    root=NULL;
}

template <typename ValType>
Map<ValType>::~Map(){
    delete root;
}


template <typename ValType>
ValType Map<ValType>::getvalue(string key){
    node *found=treeSearch(key,root);
    if(found==NULL)
        cout<<"Couldnot Found the node";
    else return found->value;
}

template <typename ValType>
typename Map<ValType>::node *Map<ValType>::treeSearch(string key,node *t){
    if(t==NULL) return NULL;

    if(t->key==key) return t;

    if(t->key>key) treeSearch(key,t->left);

    else treeSearch(key,t->right);
}

template <typename ValType>
void Map<ValType>::add(string key,ValType value){
    treeEnter(key,value,root);
}

template <typename ValType>
void Map<ValType>::treeEnter(string key,ValType value,node *&t){
    if(t==NULL){
        t->value=value;
        t->key=key;
        t->left=NULL;
        t->right=NULL;
    }

    else if(t->key==key) t->value=value;

    else if(t->key>key) treeEnter(key,value,t->left);

    else treeEnter(key,value,t->right);
}

Error:For all the functions its saying that they are already been defined.

I am following Stanford online course and the same worked for the instructor(she was using mac)

user2511713
  • 555
  • 3
  • 7
  • 18
  • 1
    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) – juanchopanza Jul 07 '13 at 14:17
  • 1
    It could be that your IDE attempts to compile anything with the `.cpp` suffix. – juanchopanza Jul 07 '13 at 14:18
  • 3
    You also have a circular include. `map.cpp` should not include `map.h`. – juanchopanza Jul 07 '13 at 14:25
  • You're using a [reserved identifier](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) as your include guard. – chris Jul 07 '13 at 14:32
  • @juanchopanza I also thought of that and remove it but its giving me different error like "missing ; before < on line 6",unrecognizable template declaration/definition,~Map illegal global destructor – user2511713 Jul 07 '13 at 14:33
  • 1
    See my first comment. You *have* to remove the include. – juanchopanza Jul 07 '13 at 14:33
  • tried.Not working.Same error – user2511713 Jul 07 '13 at 14:40
  • 1
    juanchopanza is correct. Actually you will most likely have to put all the code in the header file anyway, or you will get unresolved externals when linking once you put the map in a library and attempt to use it from there. – Dabbler Jul 07 '13 at 14:52
  • Yeah I tried to put it in one file and its working.:-).But is there not a way to make it work in two different file? – user2511713 Jul 07 '13 at 14:57
  • It will compile if you make sure that the CPP file is only included via the header file and not compiled as such (i.e. not as a separate "compilation unit", as it's called). So, for example, if you're using Visual Studio, you mustn't add the CPP file to the project. But remember you'll get those linker errors sooner or later... – Dabbler Jul 07 '13 at 15:00
  • Remove the include I mentioned, and change the suffix of the `.cpp` file to `.do_not_compile`. Or `.icpp`, or `.fred` or something. – juanchopanza Jul 07 '13 at 15:20
  • Let me add that probably calling a file `map.h`, which is also part of the standard libraries, is not a good a idea. – Antonio Jul 07 '13 at 15:43
  • @Antonio `map.h` is not part of the standard library, but `map` is, and it is close enough to cause confusion. – juanchopanza Jul 07 '13 at 16:48
  • I changed it to map1.h and I got the same issue – user2511713 Jul 07 '13 at 16:49

2 Answers2

4

You have included map.h into map.cpp and map.cpp into map.h. The include guards in map.h will prevent multiple inclusion of map.h and will prevent infinite recursive inclusion. However, if you feed map.cpp to the compiler directly (which is what you are apparently trying to do) it will include map.h once and then map.h will include map.cpp itself one more time. This is what is causing the error.

If you want to implement your template as .cpp file included into .h file, you can do that. This is weird, but it can be forced to work. First and foremost, if you decided to #include your map.cpp, then don't even attempt to compile your map.cpp. Don't feed your map.cpp directly to the compiler. Also, remove #include "map.h" from that .cpp file. There's absolutely no point in doing that.

Your program will have other implementation files, like, say, myprogram.cpp, which will use your map. That myprogram.cpp should include map.h. That myprogram.cpp is what you will feed to the compiler. That way it will work as intended. But trying to compile map.cpp directly will only result in errors.

A better idea though would be not to put anything into a .cpp file. Either put everything into .h file or, if you really want to have it split that way, rename your .cpp file into something else to make it clear to everyone that this is not a translation unit.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
1

In my case, I missed include guards or #pragma once at the top of the header where I defined a template function.

Scott Langham
  • 58,735
  • 39
  • 131
  • 204