Создание экземпляра объекта типа класса шаблона в C++

У меня возникают проблемы с созданием экземпляра объекта типа класса шаблона в C++.

Вот код:

Массив.ч:

//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

Массив.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) {

}

Основной.cpp:

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

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

Теперь, когда я навожу курсор на a в Main.cpp, я вижу следующее:

Ошибка: не существует конструктора по умолчанию для класса "Array‹7U, int>"

Но, как видите, конструктор шаблонов по умолчанию существует. Итак, что мне здесь не хватает?


person ggghahaha    schedule 30.03.2018    source источник
comment
template<size_t n, typename T> Array(void); --› Array(); stackoverflow.com/questions/495021/   -  person llllllllll    schedule 30.03.2018
comment
@liliscent, спасибо. Я читал пост раньше, но все еще не могу решить свою проблему здесь.   -  person ggghahaha    schedule 30.03.2018
comment
@gghahaha, как сказала Лилисент, вам нужно удалить лишнее template из конструктора, оно там не место. Кроме того, в вашем файле cpp вам нужно заменить все Array:: на Array<n, T>::   -  person Remy Lebeau    schedule 30.03.2018
comment
C++ вызывает явный конструктор шаблонов   -  person songyuanyao    schedule 30.03.2018
comment
@RemyLebeau, после замены первого Array:: и удаления template я получил ошибку как неправильный синтаксис. Поэтому не вижу смысла в ваших советах.   -  person ggghahaha    schedule 30.03.2018
comment
@ggghahaha то, что я сказал ранее, действительно применимо. Но есть и другие ошибки в коде, которые тоже нужно исправлять. Тогда все работает нормально.   -  person Remy Lebeau    schedule 30.03.2018


Ответы (2)


В вашем коде несколько ошибок.

В вашем заголовочном файле вам нужно удалить лишний template из конструктора, он там не принадлежит.

В вашем файле cpp вам нужно заменить все Array:: на Array<n, T>::. Ваш конструктор должен передать n в new[]. Ваш деструктор должен delete[] массив. И operator[] нужно что-то вернуть.

В вашем классе static членов, поэтому вам также необходимо создать их экземпляры.

Попробуй это:

Массив.ч

#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

Массив.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;
}

Живое дено

person Remy Lebeau    schedule 30.03.2018
comment
Насколько я понял нельзя использовать .cpp для реализации шаблона и при этом не создавать специализацию шаблона до его использования. Я прав? - person ggghahaha; 31.03.2018
comment
@ggghahaha Вы можете отделить объявления шаблонов от определений, если они выполняются в одной и той же единице перевода, что делает этот код, имея файл .h #include файл .cpp. Если вы попытаетесь скомпилировать .cpp как отдельный модуль, это не сработает. - person Remy Lebeau; 31.03.2018

Вам не нужно использовать шаблон при объявлении методов или конструкторов внутри вашего класса. Объявленный вами конструктор является шаблонным методом внутри шаблонного класса, а не конструктором по умолчанию.

Я бы никогда не стал полагаться на ошибки от intellisense, иногда это просто неправильно, запуск компилятора обычно дает более точные и подробные сообщения об ошибках.

person Alan Birtles    schedule 30.03.2018
comment
Просто удалите оператор шаблона из объявления конструктора, затем запустите компилятор, который сообщит вам о следующей ошибке. - person Alan Birtles; 30.03.2018
comment
Так вот, вы принципиально не помогаете мне решить проблему, а меняете ее на другую. Зачем ты это делаешь? Я всегда могу удалить весь свой код и написать какую-нибудь тарабарщину, чтобы получить другую, отличную от моей ошибки. А ты как раз предлагаешь мне это сделать. Спасибо, но мне такая помощь не нужна. - person ggghahaha; 30.03.2018