0

I am trying to overload some operators in C++. They need to be overloaded because I made a template binary search tree that does a lot of equality checks and my data object is not a int or string but dates.

I got the date operators working very well. I tested them and they worked every time in testing (not in the tree, but just as objects in main). However it seemed I jumped the gun and the binary search tree just won't use them. Now upon further searching a lot of sources say the way I have made my operators is wrong.

The errors I get are (with no link to a line of code):

1>DataStore.obj : error LNK2019: unresolved external symbol "bool __cdecl operator==(class Date const &,class Date const &)" (??8@YA_NABVDate@@0@Z) referenced in function "public: void __thiscall BinarySearchTree<class Date>::insert(class Date const &)" (?insert@?$BinarySearchTree@VDate@@@@QAEXABVDate@@@Z)
1>DataStore.obj : error LNK2019: unresolved external symbol "bool __cdecl operator>(class Date const &,class Date const &)" (??O@YA_NABVDate@@0@Z) referenced in function "public: void __thiscall BinarySearchTree<class Date>::insert(class Date const &)" (?insert@?$BinarySearchTree@VDate@@@@QAEXABVDate@@@Z)
1>Z:\Dropbox\University\ICT209 - Data Structures\Assignment2\StockDataTree\Debug\StockDataTree.exe : fatal error LNK1120: 2 unresolved externals

Well these are my operators inside Date.h:

friend bool operator==(const Date &date1, const Date &date2);
friend bool operator!=(const Date &date1, const Date &date2);
friend bool operator<(const Date &date1, const Date &date2);
friend bool operator<=(const Date &date1, const Date &date2);
friend bool operator>(const Date &date1, const Date &date2);
friend bool operator>=(const Date &date1, const Date &date2);

and here is a example of how they are used in the Date.cpp:

inline bool operator==(Date &date1, Date &date2)
{
    return 
        (
        date1.getDay() == date2.getDay() &&
        date1.getMonth() == date2.getMonth() &&
        date1.getYear() == date2.getYear()
        );
}

inline bool operator!=(const Date &date1, const Date &date2)
{
    return !(date1 == date2);
}

(My binary search tree is based on the one out of C++ Programming: Program Design Including Data Structures)

This is a example of the code in the tree template to give an idea of why my custom operators are not working: (const elemType would be my date object)

BinarySearchTree.h <-- this is a template

template <class elemType>
void BinarySearchTree<elemType>::insert(const elemType& insertItem)
{
    nodeType<elemType> *current;
    nodeType<elemType> *trailCurrent;
    nodeType<elemType> *newNode;

    newNode = new nodeType<elemType>;
    newNode->info = insertItem;
    newNode->lLink = NULL;
    newNode->rLink = NULL;

    if (root == NULL)
        root = newNode;
    else
    {
        current = root;

        while (current != NULL)
        {
            trailCurrent = current;

            if (current->info == insertItem)
            {
 ............

EDIT: Also this tree works fine as int or string, with no issues.

BinarySearchTree<int> test;// this works

BinarySearchTree<string> test;// this works too

The issue is only when I use the tree with my own date class.

BinarySearchTree<Date> test;// this does not work

Also the Date class operators work in main.cpp but not in the tree.

Date tmp(12,12,2000);
Date tmp2(12,12,2000);

cout << (tmp == tmp2) << endl; // this works fine too
Joseph
  • 3,899
  • 10
  • 33
  • 52
  • 1
    Do you have references to those operators that can't see the `inline` keyword in the same translation unit? – Carl Norum May 26 '13 at 17:58
  • 1
    Perhaps you've relegated the definition of the member functions of your class template into a `.cpp` file? If so, you may want to move them to the header. See also [this](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Andy Prowl May 26 '13 at 17:58
  • @CarlNorum, how would I reference the operators? Is that by including the header file? `#include "Date.h"` in the template? – Joseph May 26 '13 at 18:12
  • 1
    I thought you said they were implemented in a `.cpp` file. It looks to me like @JoachimPileborg has answered your question already. – Carl Norum May 26 '13 at 18:14
  • @AndyProwl, The header is all in one file, nothing in `.cpp` at all. (The operators are not in the tree class however, the are in the date class and they are in the date class `.cpp` – Joseph May 26 '13 at 18:14
  • @CarlNorum, yes the operators in the date class are in a .cpp, I was under the impression that if a class is not a template then it must be split into two files? – Joseph May 26 '13 at 18:16

2 Answers2

2

From this reference:

The definition of an inline function must be present in the translation unit where it is called (not necessarily before the point of call).

And

3) An inline function with external linkage (e.g. not declared static) has the following additional properties:

1) It must be declared inline in every translation unit.

This means that if the function definitions are not in the same source file as where you call them (the first quote) it simply will not be visible in any other source file unless they are defined for all source files (the second quote).

The solution? Either don't make the function inline, or put them in a header file that is included in all source files where the functions are called.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
2

There are two problems. First, as @joachimpileborg points out, inline functions must be visible where they are used. Second, the comparison functions are declared as taking arguments of type const Date&, but defined as taking arguments of type Date&.

Pete Becker
  • 74,985
  • 8
  • 76
  • 165