0

In my programming class we're just being introduced to the concept of templates within C++. This is a concept we never covered in my class on Java last semester, and the whole syntax of C++ is really throwing me for a loop. I'm getting a long string of compilation errors with the code I will post below. It would make me think that I'm missing something very obvious within the template Syntax. The following is just an example template I'm trying to work with, something to get me started on the homework. If any of you have any insights as to why this isn't compiling, I'd be grateful. Thanks!!

keyValuePair.h

#include <fstream>
#include <iostream>
#include <string>

#ifndef KEYVALUEPAIR
#define KEYVALUEPAIR

template<class key, class value>
class keyValuePair
{
private:

key kvar;

value vvar; 

public:

keyValuePair(); //Default Constructor

void setKvar(key object1); //Method to set kvar to a value

void setVvar(value object2); //Method to set vvar to a value    

key getKvar(); //Method to return kvar

value getVvar(); //Method to return vvar

};

#include "keyValuePair.cpp"
#endif

keyValuePair.cpp

#include <iostream>
#include <fstream>
#include <string>

#include "keyValuePair.h"


template<class key, class value>;
keyValuePair<key, value>::keyValuePair()
{
}

template<class key, class value>; //return the value of kvar
key keyValuePair<key, value>::getKvar()
{
return kvar;
}

template<class key, class value>; //return the value of vvar
value keyValuePair<key, value>::getVvar()
{
return vvar;
}

template<class key, class value>; //set the value of kvar
void keyValuePair<key, value>::setKvar(key& object1)
{
object1 = kvar;
}

template<class key, class value>; //set the value of vvar
void keyValuePair<key, value>::setVvar(value& object2)
{
object2 = vvar;
}

main.cpp

#include <fstream>
#include <iostream>
#include <string>

#include "keyValuePair.h"

using namespace std; 

int main(int argc, char* argv[])
{

fstream myFile(argv[1], ios::in);
fstream fout("out.txt", ios::out); 

myFile.close();
fout.close(); 



keyValuePair<string, int> sample;

sample.setKvar("Hello World.");
sample.setVvar(3);

cout << sample.getKvar() << sample.getVvar() << "\n"; 

return 0; 
}
pgowdy13
  • 55
  • 1
  • 1
  • 9
  • 2
    Hi, welcome on StackOverflow! Please give a minimal compilable example that displays the problem. The best thing is to give a code snippet that can be pasted into one of the [online compilers[(http://isocpp.org/blog/2013/01/online-c-compilers) – TemplateRex Feb 08 '13 at 19:57
  • Posting at least the first error is helpful too. Even if it just looks like "a long string" now, it's actually telling you (and us) what's wrong. – Drew Dormann Feb 08 '13 at 20:03
  • Not your problem (yet), but useful template reading: http://www.parashift.com/c++-faq/templates-defn-vs-decl.html – JaredC Feb 08 '13 at 20:08
  • Hihi looks like the OP is not used to how blazingly fast StackOverflow answers come and therefore is not reading in real time ;) – odinthenerd Feb 08 '13 at 20:31
  • Oh my gosh, I'm not used to it at all. My assignment is due days in advance, so I posted far in advance. You guys are so quick! – pgowdy13 Feb 10 '13 at 18:28

3 Answers3

0

Remove the semicolon after template<class key, class value>:

                                !--here
template<class key, class value>; 
keyValuePair<key, value>::keyValuePair()
{
}
ecatmur
  • 152,476
  • 27
  • 293
  • 366
0

keyValuePair.h should not include keyValuePair.cpp. Also the function bodies in keyValuePair.cpp should be declaired directly (different best practaces for templates than normal functions)

template<class key, class value>
class keyValuePair
{
private:

    key kvar;

    value vvar; 

public:

    keyValuePair(){} //Default Constructor

    void setKvar(key object1){kvar = object1;} //Method to set kvar to a value

    void setVvar(value object2){vvar = object2;} //Method to set vvar to a value    

    key getKvar(){return kvar;} //Method to return kvar

    value getVvar(){return vvar;} //Method to return vvar

};

The semicolons after the

template<class key, class value>;

are a typo too.

Also your setKvar function assigns the value of kvar to the parameter taken by reference. I don't this this is what you want seeing as the function is named set.

The reason the bodies of template class member functions are usually declared in line is that the compiler will only generate code for a particular type or types (which is called instantiating the template for the particular type) if it sees them being used in that compilation unit (usually a compilation unit and a .cpp file are the same thing).

This means that if you put the function bodies in keyValuePair.cpp and try to use them in main.cpp the linker will give you "not found" errors because in the compilation unit keyValuePair.cpp the compiler could not see them being used so it never created them.

You can cause the template to be instantiated for specific types directly like this:

template keyValuePair<int,long>;

however this is probably bad style because every time you want to use your template with new types you need to add these declarations to your keyValuePair.cpp file which defeats the purpose of having the flexibility in the first place.

odinthenerd
  • 5,422
  • 1
  • 32
  • 61
  • Wow, thank you guys so much. You're not going to believe this (or maybe you will), but my textbook includes the semicolons after all of the template declarations. My professor sent an email out today telling us about this typo. Needless to say, it was an incredibly frustrating error to try to figure out when your source of information is wrong. Again, thank you guys! I'd upvote you if I weren't so new :). – pgowdy13 Feb 10 '13 at 18:26
  • most textbooks are crap! These are the good ones: http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – odinthenerd Feb 11 '13 at 20:22
0

You have several small mistakes in the syntax.

  • you declared setKvar and setVvar to take the parameter by value, but defined them to take a reference. (Drop the & in .cpp file)

  • Do not put a semicolon after template<class key, class value>

  • in setKvar and setVvar, you have the argumets swapped in the assignment. It should read like kvar = object1; in setKvar and analogically vvar = object2; in setVvar

  • Do not include the cpp file in the header, include the content directly into the header file, like PorkyBrain said.

v154c1
  • 1,698
  • 11
  • 19