1

I've got a form of an array class that uses templates. Because it is using templates, the entire class is declared and defined in the header file.

template<typename Type>
class KSArray
{
    friend bool operator==(const KSArray &lhs, const KSArray &rhs);
    friend bool operator<(const KSArray &lhs, const KSArray &rhs);

public:
    typedef size_t size_type;
    typedef Type value_type;

    KSArray();
    KSArray(const KSArray &k);
    KSArray& operator=(const KSArray &rhs);
    ~KSArray();
    KSArray(int n);
    KSArray(int n, value_type t);

    value_type& operator[](int index);
    const value_type& operator[](int index) const;

    size_type size() const;
    value_type* begin();
    value_type* begin() const;
    value_type* end();
    value_type* end() const;

private:
    size_type _size;
    value_type* _arrayPtr;
};

I've defined all of the functions and most of them work except the == and < operators. They are defined as follows:

template<typename Type>
bool operator==(const KSArray<Type> &lhs, const KSArray<Type> &rhs)
{
    if(lhs._arrayPtr==rhs._arrayPtr)
    {
        return true;
    }
    else if(lhs._size==rhs._size)
    {
        for(size_t i=0;i<lhs._size;++i)
        {
            if(lhs->_arrayPtr[i]!=rhs->_arrayPtr[i])
            {
                return false;
            }
            else
            {
                continue;
            }
        }

        return true;
    }
    else
    {
        return false;
    }
}

template<typename Type>
bool operator<(const KSArray<Type> &lhs, const KSArray<Type> &rhs)
{
    if(lhs==rhs)
    {
        return false;
    }
    else
    {
        for(int i=0;i<min(lhs._size,rhs._size);++i)
        {
            if(lhs->_arrayPtr[i]==rhs->arrayPtr[i])
            {
                continue;
            }
            else if(lhs->_arrayPtr[i]<rhs->arrayPtr[i])
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        return (lhs._size<rhs._size);
    }
}

When I run this code with my test file in main, I get a few linker errors:

Undefined symbols for architecture x86_64:
  "operator==(KSArray<int> const&, KSArray<int> const&)", referenced from:
      test_class_KSArray_equality_comparisons(Tester&) in ksarray_test.o
      bool operator!=<int>(KSArray<int> const&, KSArray<int> const&) in ksarray_test.o
      bool operator<=<int>(KSArray<int> const&, KSArray<int> const&) in ksarray_test.o
      bool operator><int>(KSArray<int> const&, KSArray<int> const&) in ksarray_test.o
  "operator<(KSArray<int> const&, KSArray<int> const&)", referenced from:
      test_class_KSArray_order_comparisons(Tester&) in ksarray_test.o
      bool operator<=<int>(KSArray<int> const&, KSArray<int> const&) in ksarray_test.o
      bool operator><int>(KSArray<int> const&, KSArray<int> const&) in ksarray_test.o
      bool operator>=<int>(KSArray<int> const&, KSArray<int> const&) in ksarray_test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

As the error suggests, I use the == and < operators in my other operators in order to minimize the code I have to write. From the research I've done, I think the issue is with my placement of const and perhaps Type. I've tried moving them around and tweaking them to no avail. Any ideas?

I'm using XCode 4.6 with the Apple LLVM 4.2 C++ compiler on Mac OS X 10.8.2.

  • So right out of the gate, please specify the **filename** that each of the aforementioned code slices are contained in. If what I'm thinking is the problem, you should follow that up with reading [this question and answer set](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file/495056#495056) to understand why templates (***including free-function operators like your comparison operators***) must be implemented in a *header file*. I don't think it coincidence these two code chunks (class and ops) are in different snippet blocks in your question. – WhozCraig Feb 17 '13 at 06:13

2 Answers2

0

Can you please try explicit keyword before your constructor. It looks like to me that you are facing problem of conversion constructor and your int argument is implicitly getting converted into KSArray..

user258367
  • 3,247
  • 2
  • 18
  • 17
0

After talking to my professor, I found out that templates and friends work slightly oddly: http://www.parashift.com/c++-faq/template-friends.html

Using the above link, I was able to figure out how to fix my issue. During my initial research, I wasn't aware that the issue dealt with friends and templates. I thought it was an issue with const or something weird.