Добрый день, возникла следующая проблема касающаяся шаблонных классов в C++.
Структура проекта следующая:
Имеет значение что есть три *.h файла, они располагаются ниже. В первом классе имеется структура Triplet и класс в котором интересен метод void CalculateLocalPositions()
.
// ----------------------
// second_task_manager.h
// ----------------------
struct Triplet
{
std::string dotName;
std::string dotKeyPoints;
int interpolationOrder;
Triplet() :
dotName(""), dotKeyPoints(""), interpolationOrder(0) {}
Triplet(std::string dotName, std::string dotKeyPoints, int order) :
dotName(dotName), dotKeyPoints(dotKeyPoints), interpolationOrder(order) {}
};
template<typename T>
class SecondTaskManager
{
public:
SecondTaskManager(const double T, std::string dotsFileName, std::string conditionsFileName);
...
LocalSolver<T>* localSoverPtr_;
void CalculateLocalPositions(); // ЭТОТ МЕТОД!!!
private:
std::vector<Triplet> triplets_;
};
#include"second_task_manager_impl.h"
Реализация отмеченного метода показана ниже, и хранится в другом *.h файле (предыдущая строка кода подключает его). Из реализации видно что интересный мне метод вызывает метод класса LocalSolver
через указатель.
// --------------------------
// second_task_manager_impl.h
// --------------------------
template<typename T>
inline void SecondTaskManager<T>::CalculateLocalPositions()
{
std::vector<DotPosPair<T>> lol;
localSoverPtr_->CalculateDotsLocalPos(triplets_);//(triplets_, &lol);
}
В самом классе LocalSolver данный метод реализован следующим образом (В качестве аргумента передается вектор из триплетов std::vector<Triplet> & triplets
).
// ----------------------
// local_pos_solver.h
// ----------------------
#include"../SecTaskManager/second_task_manager.h"
template<typename T>
class LocalSolver
{
public:
LocalSolver();
~LocalSolver();
void CalculateDotsLocalPos(std::vector<Triplet> & triplets)
{ std::cout << "lol\n" }
private:
InterpolationSolver<T>* solverPtr_;
double T_;
};
И при компиляции возникает ряд ошибок, и я никак не пойму из-за чего.
Текст ошибок:
Ошибка C3203 "allocator": неспециализированный класс шаблон нельзя использовать в качестве аргумента шаблон для параметра шаблон "_Alloc", требуется действительный тип
Ошибка C2923 std::vector: "Triplet" не является допустимым аргументом типа шаблон для параметра "_Ty"
Ошибка C2065 Triplet: необъявленный идентификатор
Сам main.cpp:
#include"SecondTask\SecTaskManager\second_task_manager.h"
int main()
{
using std::cout;
using std::endl;
try
{
SecondTaskManager<float> manager(1.4, "SecondTaskFiles/dots", "/SecondTaskFiles/conditions");
manager.CalculateLocalPositions(); // ВОТ МЕСТО ВЫЗОВА
}
catch (const std::exception& ex)
{
std::cout << ex.what();
}
...
}
Тот факт, что определение шаблона class SecondTaskManager
в заголовочном файле second_task_manager.h
содержит в себе
LocalSolver<T>* localSoverPtr_;
намекает на то, что local_pos_solver.h
у вас включается в second_task_manager.h
(хоть это и не видно явно из того кода, который вы привели).
При этом local_pos_solver.h
также явно включает в себя second_task_manager.h
.
Если это так, то налицо зацикленное включение заголовочных файлов, которое сразу и объясняет происходящее.
Так и не разобрался в чем была ошибка, (возможно зацикливание при подключении *.h файлов или еще что-то). Разрешил проблему использованием std::tuple
.
Можете объяснить, когда возникает эта ошибка и как от нее избавиться?