Шаблонные класcы C++. C3203

839
06 февраля 2017, 16:47

Добрый день, возникла следующая проблема касающаяся шаблонных классов в 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();
    }
    ...
}
Answer 1

Тот факт, что определение шаблона 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.

Если это так, то налицо зацикленное включение заголовочных файлов, которое сразу и объясняет происходящее.

Answer 2

Так и не разобрался в чем была ошибка, (возможно зацикливание при подключении *.h файлов или еще что-то). Разрешил проблему использованием std::tuple.

READ ALSO
Ошибка Stack overflow, как избежать и что это?

Ошибка Stack overflow, как избежать и что это?

Можете объяснить, когда возникает эта ошибка и как от нее избавиться?

837
Visual studio 2012 пишет Symbols loaded

Visual studio 2012 пишет Symbols loaded

Когда запускаю любой проект она мне пишет

822
CMake ошибка в CLion

CMake ошибка в CLion

Всем привет

860