0

I am trying to instantiate my sarray class.

sarray array(10);

But I get an error saying that their is no constructor which has a matching definition.

The constructor is defined in the sarray header file

#ifndef SARRAY_H
#define SARRAY_H
template <class T>
class sarray {
public:
    template<class T>sarray(int size);
    ~sarray();
    template<class T> T& operator[](int i);
private:
    int size;
    T* data;
};

And is implemented in the sarray cpp file:

template<class T> sarray::sarray(int size)
    : size(size)
{
    if (size > 0) data = new T[size];
    else {
        cout << "illegal array size = " << size << endl;
        exit(1);
    }
}

Do I need to specify that I am using templates in the constructor call? The constructor argurments and the call arguments match so I am confused by the error message.

VS Syntax Error Message

C++ argument list for class template is missing

Full Source Code

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

template<class T> sarray::sarray(int size)
    : size(size)
{
    if (size > 0) data = new T[size];
    else {
        cout << "illegal array size = " << size << endl;
        exit(1);
    }
}
sarray::~sarray()
{
    delete[] data;
}
template<class T> T& sarray::operator[](int i)
{
    if (i < 0 || i >= size) {
        cout << "index " << i << " is out of bounds." << endl;
        exit(1);
    }
    return data[i];
}
Lyra Orwell
  • 1,048
  • 4
  • 17
  • 46
  • 2
    Please post a [Minimal, Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example). What is `data`? – MikeCAT Oct 30 '20 at 13:43
  • 2
    Note that you shouldn't write template definitions in a cpp file. – cigien Oct 30 '20 at 13:44
  • 2
    Seems related but not seem duplicate now: [c++ - Why can templates only be implemented in the header file? - Stack Overflow](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – MikeCAT Oct 30 '20 at 13:45
  • 3
    please include the complete error message in the question. When I try here: https://godbolt.org/z/oh13fe the problem is that there is no way to deduce `T` from `sarray array(10);` – 463035818_is_not_an_ai Oct 30 '20 at 13:47
  • 1
    A template constructor with a template parameter that can't be deduced? I suppose you have to remove the `template ` part before the constructor declaration. – max66 Oct 30 '20 at 13:49
  • 4
    I suppose you want `sarray` to be a template, parametrized on `T`, however why you made also the constructor and `operator[]` a template is unclear. My guess is that you want a class template and the methods need not be templates – 463035818_is_not_an_ai Oct 30 '20 at 13:50
  • 1
    please clarify if `operator[]` and the constructor really should be templates. The fact that you also used `T` for their parameter name makes me think no – 463035818_is_not_an_ai Oct 30 '20 at 13:51
  • 1
    I think the syntax should be something like `sarray array(10);` – Harry Oct 30 '20 at 13:55
  • @idclev463035818 is most likely right that you don't need the `template` specification before the constructor declaration. However, as your constructor's signature doesn't depend on the tempate argument, your compiler can't deduce which specialization to use, so @Harry is right, too. – starturtle Oct 30 '20 at 13:59
  • @starturle its a method template of a class template, that both parameters have the same name is only coincidence, or due to a misunderstanding of OP, thats what I tried to find out. `sarray array(10);` also wont work for OPs declaration – 463035818_is_not_an_ai Oct 30 '20 at 14:02

1 Answers1

1

The template<class T> on top of you class affects the whole class. You do not need to keep adding template<class T> in front of all methods of the class. You do need to do it in the definitions of the methods, when you are writing them outside the class. So your class should become:

template <class T>
class sarray {
public:
    sarray(int size);
    ~sarray();
    T& operator[](int i);
private:
    int size;
    T* data;
};

And then the definitions of the methods would look like:

template<class T> sarray<T>::sarray(int size)
    : size(size)
{
    if (size > 0) data = new T[size];
    else {
        cout << "illegal array size = " << size << endl;
        exit(1);
    }
}

template<class T> sarray<T>::~sarray()
{
    delete[] data;
}

template<class T> T& sarray<T>::operator[](int i)
{
    if (i < 0 || i >= size) {
        cout << "index " << i << " is out of bounds." << endl;
        exit(1);
    }
    return data[i];
}

However, as people have commented, it is not a good idea to define the methods of a template class in a separate .cpp file. You could look around the internet for the full explanation why, as it would be too long for here.

If you still want them to be out of the class' declaration (but still in the same header file) for e.g. better readability, then you could do it the shown way.

Lyubomir Vasilev
  • 3,000
  • 17
  • 24