1

I am new to templated classes. I am working on converting an original class to a templated class while doing so I get an error stating that I do not have an appropriate default constructor available. If I remember correctly a default constructor should be a constructor with no parameters. Any type of guidance to the right direction would be appreciated.

UPDATE REMOVED The parameterless constructor since its the same as the one with the DEFAULT_VALUE variables

Header file:

#include <iostream>


namespace cs_pairs 
{
    template <class T>
    class OrderedPair 
    {
    public:

        //static const int DEFAULT_VALUE = int();
        static const int DEFAULT_VALUE;

        typedef std::size_t size_type;
        typedef T value_type;

        OrderedPair(value_type newFirst = DEFAULT_VALUE, value_type newSecond = DEFAULT_VALUE);
        void setFirst(value_type newFirst);
        void setSecond(value_type newSecond);
        value_type getFirst() const;
        value_type getSecond() const;
        OrderedPair operator+(const OrderedPair& right) const;
        bool operator<(const OrderedPair& right) const;
        void print() const;

        class DuplicateMemberError
        {

        };

    private:
        value_type first;
        value_type second;
    };


    //template <class T>
    //const int OrderedPair<T>::DEFAULT_VALUE = int();

}

Implementation File:

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

namespace cs_pairs {

    template <class T>
    OrderedPair<T>::OrderedPair(value_type newFirst, value_type newSecond) {
        setFirst(newFirst);
        setSecond(newSecond);
    }

    template <class T>
    void OrderedPair<T>::setFirst(value_type newFirst) {
        // if statement to throw an exception if precondition not met goes here.        
        first = newFirst;
    }

    template <class T>
    void OrderedPair<T>::setSecond(value_type newSecond) {
        // if statement to throw an exception if precondition not met goes here.    
        second = newSecond;
    }

    template <class T>
    typename OrderedPair<T>::value_type OrderedPair<T>::getFirst() const {
        return first;
    }

    template <class T>
    typename OrderedPair<T>::value_type OrderedPair<T>::getSecond() const {
        return second;
    }

    template <class T>
    OrderedPair<T> OrderedPair<T>::operator+(const OrderedPair<T>& right) const {
        return OrderedPair(first + right.first, second + right.second);
    }

    template <class T>
    bool OrderedPair<T>::operator<(const OrderedPair<T>& right) const {
        return first + second < right.first + right.second;
    }

    template <class T>
    void OrderedPair<T>::print() const {
        cout << "(" << first << ", " << second << ")";
    }
}

Client File Section where I first encounter the error:

#include <iostream>
#include <ctime>
#include <cstdlib>
#include "orderedpair.h"
using namespace std;
using namespace cs_pairs;

int main() {
    int num1, num2;
    OrderedPair<int> myList[10];
   }
Debug
  • 127
  • 2
  • 10
  • 2
    That's not the only error I get and certainly not the most important. You need to define `DEFAULT_VALUE` somewhere. Since you have default parameters for your constructor you'll need to remove the one without parameters otherwise it is an ambiguous call since both match. Most important, you need to specify the template parameter: `OrderedPair myList[10];` or whichever type you plan to use. – Retired Ninja Aug 23 '20 at 07:45
  • @RetiredNinja `static int` is automatically set to zero. – Rohan Bari Aug 23 '20 at 07:46
  • @RohanBari Without it explicitly initialized or defined outside the class as you normally would with static variables I get `error LNK2001: unresolved external symbol "public: static int const OrderedPair::DEFAULT_VALUE" (?DEFAULT_VALUE@?$OrderedPair@H@@2HB)` Presumably, unless the pair will always hold ints you'd want something like `inline static const T DEFAULT_VALUE = T {};` I am unsure why `inline` is necessary but it is an error without it when the template type is `double` or another class. – Retired Ninja Aug 23 '20 at 07:54
  • I eliminated 17 errors from my previous compile, now down to 7. The criteria for this program is being able to use an ordered pair of string instead of ints as well. So would static const T DEFAULT_VALUE = T {}; be recommended. Sadly the default constructor error is still in place. – Debug Aug 23 '20 at 07:55
  • This works for me: https://ideone.com/IYa82P It is helpful to copy/paste the full error messages in your question and to not keep editing it to fix things that are mentioned since if you continue to do that you'll have a question where the code works and nobody knows why you asked it in the first place. – Retired Ninja Aug 23 '20 at 08:12
  • I keep getting error LNK2019 when compiling stating, >"Error LNK2019 unresolved external symbol "public: __thiscall >cs_pairs::OrderedPair::OrderedPair(int,int)" (??0? >$OrderedPair@H@cs_pairs@@QAE@HH@Z) referenced in function "public: >void __thiscall cs_pairs::OrderedPair::`default constructor closure'(void)" (?? > _F?$OrderedPair@H@cs_pairs@@QAEXXZ)" – Debug Aug 23 '20 at 08:33
  • The issue you might be having is that templates must be implemented in header files. You can split the header and implementation if you like but the general way to do that is to name the file something like implementation.inl and include it in the header file at the end. You should read this: https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – Retired Ninja Aug 23 '20 at 20:49

0 Answers0