1

I am having troubles instantiating an object of a template class type in C++.

Here is the code:

Array.h:

//Developed by Trofimov Yaroslav on 30.03.2018

#ifndef _ARRAY_H_TROFIMOV_
#define _ARRAY_H_TROFIMOV_

template<size_t n, typename T>
class Array
{
        static unsigned __freeId, __quantity;
        unsigned _id;

        T* _array;
public:
        template<size_t n, typename T>
        Array(void);
        ~Array(void);
        T& operator[](const size_t);
};
#include "Array.cpp"

#endif

Array.cpp:

//Developed by Trofimov Yaroslav on 30.03.2018
#include "Array.h"

template<size_t n, typename T>
Array::Array(void) 
    : _id(++__freeId), _array(new T[]) {

}

template<size_t n, typename T>
Array::~Array(void) {

}

template<size_t n, typename T>
T& Array::operator[](const size_t i) {

}

Main.cpp:

//Developed by Trofimov Yaroslav on 30.03.2018
#include <iostream>
#include "Array.h"

int main(void) {
    Array<7, int> a;
    return 0;
}

Now when I hover over a in Main.cpp I see the following:

Error: no default constructor exists for class "Array<7U, int>"

But as you can see, the default template constructor does exist. So, what am I missing here?

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
ggghahaha
  • 55
  • 1
  • 8
  • 1
    `template Array(void);` --> `Array();` https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file – llllllllll Mar 30 '18 at 06:37
  • @liliscent, thanks. I read the post before, but still I can not tackle my issue here. – ggghahaha Mar 30 '18 at 06:44
  • @ggghahaha like liliscent said, you need to remove the extra `template` from the constructor, it doesn't belong there. Also, in your cpp file, you need to replace all of the `Array::` with `Array::` – Remy Lebeau Mar 30 '18 at 06:48
  • [C++ invoke explicit template constructor](https://stackoverflow.com/q/2786946/3309790) – songyuanyao Mar 30 '18 at 06:49
  • @RemyLebeau, after replacing the first `Array::` and removing `template` I got the error as a wrong syntaxis. Hence, I see no use in you advice. – ggghahaha Mar 30 '18 at 11:44
  • @ggghahaha what I said earlier does apply. But there are other errors in the code that also have to be fixed, too. [Then it works fine](https://ideone.com/6Tdcgh). – Remy Lebeau Mar 30 '18 at 16:22

2 Answers2

1

You don't need to use template when declaring methods or constructors inside your class. The constructor you've declared is a templated method inside a templated class rather than a default constructor.

I'd never rely on errors from intellisense, sometimes it's plain wrong, running the compiler will generally produce more accurate more detailed error messages.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Just delete the template statement from your constructor declaration, then run the compiler which will tell you your next error – Alan Birtles Mar 30 '18 at 06:54
  • So, you basically do not help me to solve the problem, but change it to another one. What for are you doing that? I can always delete all my code and write some gibberish to get another - different from my error. And you are just proposing me to do that. Thank you, but I do not need such a help. – ggghahaha Mar 30 '18 at 11:46
1

There are multiple errors in your code.

In your header file, you need to remove the extra template from the constructor, it doesn't belong there.

In your cpp file, you need to replace all of the Array:: with Array<n, T>::. Your constructor needs to pass n to new[]. Your destructor needs to delete[] the array. And operator[] needs to return something.

Your class has static members, so you need to instantiate instances of them as well.

Try this:

Array.h

#ifndef _ARRAY_H_TROFIMOV_
#define _ARRAY_H_TROFIMOV_ 

template<size_t n, typename T>
class Array
{
        static unsigned __freeId, __quantity;
        unsigned _id;

        T* _array;
public:
        Array(void);
        ~Array(void);
        T& operator[](const size_t);
};

#include "Array.cpp"

#endif

Array.cpp

#include "Array.h" 

template<size_t n, typename T>
Array<n, T>::Array(void) 
    : _id(++__freeId), _array(new T[n]) {
}

template<size_t n, typename T>
Array<n, T>::~Array(void) {
    delete[] _array;
}

template<size_t n, typename T>
T& Array<n, T>::operator[](const size_t i) {
    return _array[i];
}

Main.cpp

#include "Array.h"

template<> unsigned Array<7, int>::__freeId = 0;
template<> unsigned Array<7, int>::__quantity = 0;

int main() {
    Array<7, int> a;
    return 0;
}

Live deno

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • As far as I understood it is impossible to use `.cpp` for a template implementation and at the same time not to create template specialization beforehand of its usage. Am I right? – ggghahaha Mar 31 '18 at 09:14
  • @ggghahaha You can separate template declarations from definitions, as long as they are done in the same translation unit, which this code does by having the `.h` file `#include` the `.cpp` file. If you tried to compile the `.cpp` as its own unit, then it wouldn't work. – Remy Lebeau Mar 31 '18 at 16:23