Thread: Template <class T1, class T2, class T3> error LNK2019

  1. #1
    Registered User
    Join Date
    Jul 2004
    Posts
    5

    Question Template <class T1, class T2, class T3> error LNK2019

    Thanks for taking the time to read my post in advance.

    I am using templates with classes and keep getting LINK error's from visual studio.net. The code is below.

    Template.h
    Code:
    /* Vector.h
     * CS-260
     *
     * This file declares a class called Swap which
     * swaps the to variables passed by it.
     */
    
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    //Base template that will swap the data of two variable passed to it
    template <class T>
    T swap(const T &a, const T &b)
    {
    	T temp;
    
    	&temp = *&a;
    	*&a = *&b;
    	*&b = &temp;
    }
    
    //Specialized template that swaps variables of type char*
    template <class T>
    void swap(char*& first, char*& second)
    {
    	char *temp;
    	strcpy(temp, first);
    	strcpy(first, second);
    	strcpy(second, temp);
    }
    
    //Class Tripple
    template <class T1, class T2, class T3>
    class Triple
    {
    private:
    	T1 first;
    	T2 second;
    	T3 third;
    
    public:
    	//Constructors
    	Triple();
    	Triple(const T1 &a, const T2 &b, const T3 &c);
    
    	//Destructor
    	virtual ~Triple();
    
    	//Accessors
    	void setT1(Triple &lhs, T1 &rhs);
    	void setT2(Triple &lhs, T2 &rhs);
    	void setT3(Triple &lhs, T3 &rhs);
    
    	//Operators
    	friend ostream& operator<<(ostream& os, const Triple &rhs)
    	{
    		os << rhs.first << "\n"
    		   << rhs.second << "\n"
    		   << rhs.third << "\n";
    
    		return os;
    	}
    
    };
    Template.cpp
    Code:
    #include "Vector.h"
    
    //Default Constructor
    template <class T1, class T2, class T3>
    Triple<T1, T2, T3>::Triple()
    {
    	first = NULL;
    	second = NULL;
    	third = NULL;
    }
    
    //Initial value contructor
    template <class T1, class T2, class T3>
    Triple<T1, T2, T3>::Triple(const T1 &a, const T2 &b, const T3 &c)
    {
    	first = a;
    	second = b;
    	third = c;
    }
    
    //Set member functions
    template <class T1, class T2, class T3>
    void Triple<T1, T2, T3>::setT1(Triple &lhs, T1 &rhs)
    {
    	lhs.first = T1;
    }
    
    template <class T1, class T2, class T3>
    void Triple<T1, T2, T3>::setT2(Triple &lhs, T2 &rhs)
    {
    	lhs.second = T2;
    }
    
    template <class T1, class T2, class T3>
    void Triple<T1, T2, T3>::setT3(Triple &lhs, T3 &rhs)
    {
    	lhs.third = T3;
    }
    Main.cpp
    Code:
    #include "Vector.h"
    
    int main()
    {
    	//Test base class
    	int age = 22;
    	int income = 50000;
    
    	//Print original values
    	cout << "Age is " << age << "\n"
    		 << "Income is " << income << "\n\n";
    
    	//Swap data of two variables passed
    	swap(age, income);
    
    	//Print new values
    	cout << "Age is " << age << "\n"
    		 << "Income is " << income << "\n\n";
    
    	// Test specialized class
    	char *firstName = "Jonathan";
    	char *lastName = "Antoine";
    
    	//Print original values
    	cout << "My first name is " << firstName << "\n" 
    		 << "My last name is " << lastName << "\n\n";
    
    	//Swap data of two variables passed
    	swap(firstName, lastName);
    
    	//Print new values
    	cout << "My first name is " << firstName << "\n" 
    		 << "My last name is " << lastName << "\n\n";
    
    	//Test Triple Class Default constructor
    	Triple<char*, int, char*> Address1;
    	char *recipientName = "Jonathan Antoine";
    	int houseNumber = 53070;
    	char *streetName = "NW Manor Dr.";
    
    	Address1.setT1(Address1, recipientName);
    	Address1.setT2(Address1, houseNumber);
    	Address1.setT3(Address1, streetName);
    
    	Triple<char*, char*, int> Address2;
    	char *city = "Scappoose";
    	char *state = "OR";
    	int zip = 97056;
    
    	Address2.setT1(Address2, city);
    	Address2.setT2(Address2, state);
    	Address2.setT3(Address2, zip);
    
    	cout << Address1 << "\n" << Address2 << "\n";
    }
    Thanks again in advance.

  2. #2
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Put all the code in template.cpp into template.h.
    Delete template.cpp.

    Or rename template.cpp to template.hpp.
    And put #include "template.hpp" at the bottom of template.h.

    gg

  3. #3
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    Your swap template is incorrect.
    Your char* template specialization of swap is incorrect (algorithmically).
    You should put your swap implementations within their own namespace to avoid collision with std::swap.

    gg
    Last edited by Codeplug; 10-10-2004 at 08:45 PM.

  4. #4
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    Ok. I have converted everything to template.h and am now getting only two errors. They are both the same and are listed below. Code is also shown.

    Lab2 error LNK2019: unresolved external symbol "public: virtual __thiscall Triple<char *,char *,int>::~Triple<char *,char *,int>(void)" (??1?$Triple@PADPADH@@UAE@XZ) referenced in function _main

    Template.h
    Code:
    /* Template.h
     * CS-260
     *
     * This file declares a class called Swap which
     * swaps the to variables passed by it.
     */
    
    #include <iostream>
    #include <cstring>
    using namespace std;
    
    //Base template that will swap the data of two variable passed to it
    template <class T>
    T swap(const T &a, const T &b)
    {
    	T temp;
    
    	&temp = *&a;
    	*&a = *&b;
    	*&b = &temp;
    }
    
    //Specialized template that swaps variables of type char*
    template <class T>
    void swap(char*& first, char*& second)
    {
    	char *temp;
    	strcpy(temp, first);
    	strcpy(first, second);
    	strcpy(second, temp);
    }
    
    //Class Tripple
    template <class T1, class T2, class T3>
    class Triple
    {
    private:
    	T1 first;
    	T2 second;
    	T3 third;
    
    public:
    	//Constructors
    	Triple();
    	Triple(const T1 &a, const T2 &b, const T3 &c);
    
    	//Destructor
    	virtual ~Triple();
    
    	//Accessors
    	void setT1(Triple &lhs, T1 &rhs);
    	void setT2(Triple &lhs, T2 &rhs);
    	void setT3(Triple &lhs, T3 &rhs);
    
    	//Operators
    	friend ostream& operator<<(ostream& os, const Triple &rhs)
    	{
    		os << rhs.first << "\n"
    		   << rhs.second << "\n"
    		   << rhs.third << "\n";
    
    		return os;
    	}
    
    };
    
    //Default Constructor
    template <class T1, class T2, class T3>
    Triple<T1, T2, T3>::Triple()
    {
    	first = NULL;
    	second = NULL;
    	third = NULL;
    }
    
    //Initial value contructor
    template <class T1, class T2, class T3>
    Triple<T1, T2, T3>::Triple(const T1 &a, const T2 &b, const T3 &c)
    {
    	first = a;
    	second = b;
    	third = c;
    }
    
    //Set member functions
    template <class T1, class T2, class T3>
    void Triple<T1, T2, T3>::setT1(Triple &lhs, T1 &rhs)
    {
    	lhs.first = rhs;
    }
    
    template <class T1, class T2, class T3>
    void Triple<T1, T2, T3>::setT2(Triple &lhs, T2 &rhs)
    {
    	lhs.second = rhs;
    }
    
    template <class T1, class T2, class T3>
    void Triple<T1, T2, T3>::setT3(Triple &lhs, T3 &rhs)
    {
    	lhs.third = rhs;
    }
    Main.cpp
    Code:
    #include "Vector.h"
    
    int main()
    {
    	//Test base class
    	int age = 22;
    	int income = 50000;
    
    	//Print original values
    	cout << "Age is " << age << "\n"
    		 << "Income is " << income << "\n\n";
    
    	//Swap data of two variables passed
    	swap(age, income);
    
    	//Print new values
    	cout << "Age is " << age << "\n"
    		 << "Income is " << income << "\n\n";
    
    	// Test specialized class
    	char *firstName = "Jonathan";
    	char *lastName = "Antoine";
    
    	//Print original values
    	cout << "My first name is " << firstName << "\n" 
    		 << "My last name is " << lastName << "\n\n";
    
    	//Swap data of two variables passed
    	swap(firstName, lastName);
    
    	//Print new values
    	cout << "My first name is " << firstName << "\n" 
    		 << "My last name is " << lastName << "\n\n";
    
    	//Test Triple Class Default constructor
    	Triple<char*, int, char*> Address1;
    	char *recipientName = "Jonathan Antoine";
    	int houseNumber = 53070;
    	char *streetName = "NW Manor Dr.";
    
    	Address1.setT1(Address1, recipientName);
    	Address1.setT2(Address1, houseNumber);
    	Address1.setT3(Address1, streetName);
    
    	Triple<char*, char*, int> Address2;
    	char *city = "Scappoose";
    	char *state = "OR";
    	int zip = 97056;
    
    	Address2.setT1(Address2, city);
    	Address2.setT2(Address2, state);
    	Address2.setT3(Address2, zip);
    
    	cout << Address1 << "\n" << Address2 << "\n";
    }
    Thx for any help.

  5. #5
    Registered User
    Join Date
    Jun 2003
    Posts
    361
    Firstly: int main()
    Make sure you're returning a value at the end of your main function, return 0; does the trick.

    The error seems to have something to do with the deconstructor of your class, which could, in turn, be linked to the above problem. Try adding this first and see what happens...

  6. #6
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    Added return 0;. Still getting same error.

  7. #7
    Registered User Codeplug's Avatar
    Join Date
    Mar 2003
    Posts
    4,981
    >> ... unresolved external symbol ...
    The linker can't find it - try to decipher what "it" is.

    gg

  8. #8
    Registered User
    Join Date
    Jul 2004
    Posts
    5
    Thanks all so much for the help. I did not have my deconstructor defined in my code. I only had it initialized.

  9. #9
    Registered User jlou's Avatar
    Join Date
    Jul 2003
    Posts
    1,090
    Quote Originally Posted by Epo
    Firstly: int main()
    Make sure you're returning a value at the end of your main function, return 0; does the trick.
    Not necessary, for the main function (only), the return statement can be left out and a return 0 will be assumed by most modern compilers.

  10. #10
    Carnivore ('-'v) Hunter2's Avatar
    Join Date
    May 2002
    Posts
    2,879
    >>*&a...
    Just like to point out, *& is unneccessary. & takes address of, * finds value at address; combined, you end up with the same thing.

    i.e. *&a is exactly the same as a
    Just Google It. √

    (\ /)
    ( . .)
    c(")(") This is bunny. Copy and paste bunny into your signature to help him gain world domination.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. user defined template question
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-25-2006, 05:01 AM
  2. template class default constructor problem
    By kocika73 in forum C++ Programming
    Replies: 3
    Last Post: 04-22-2006, 09:42 PM
  3. Linked list with two class types within template.
    By SilasP in forum C++ Programming
    Replies: 3
    Last Post: 02-09-2002, 06:13 AM
  4. Template Class for Linked List
    By pecymanski in forum C++ Programming
    Replies: 2
    Last Post: 12-04-2001, 09:07 PM
  5. oh me oh my hash maps up the wazoo
    By DarkDays in forum C++ Programming
    Replies: 5
    Last Post: 11-30-2001, 12:54 PM