powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Не видит реализации класса
26 сообщений из 26, показаны все 2 страниц
Не видит реализации класса
    #39453861
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Qt Creator 4.2.1

h- файл:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
#ifndef TASK_MANAGER_H
#define TASK_MANAGER_H

#include <QThreadPool>

namespace MyLib
{
    template <class Type> class task_manager : public QThreadPool
    {
    public:
        //конструктор
        task_manager();
    };

}
#endif // TASK_MANAGER_H



cpp- файл:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
#include "task_manager.h"

template <class Type>
MyLib::task_manager<Type>::task_manager()
{
    
}



В main на строчке получаю ошибку:
Код: plaintext
1.
MyLib::task_manager<QString> Tasks;



/home/work/.qt/Reseaches/CompareFiles/CompareFiles.cpp:30: ошибка: undefined reference to `MyLib::task_manager<QString>::task_manager()'

Почему???
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39453864
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В h и cpp -файлы добавил:
Код: plaintext
1.
#include <QString>



Не помогло.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39453866
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Причем если реализовать класс без шаблона, то все отлично работает...
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39453898
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLПочему???
Потому что у тебя действительно нет реализации шаблона для типа QString. Собственно, её
вообще нет ни для какого типа. Если не хочешь реализацию делать прямо в заголовке, пиши так:
Код: sql
1.
2.
3.
4.
MyLib::task_manager<QString>::task_manager()
{

}


Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39453922
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLnamespace MyLib
{
template <class Type> class task_manager : public QThreadPool
{
...

Почему???

Реализации шаблонных классов и функций должны быть доступны в виде определений соотв. функций и данных во всех местах, где производится их инстанциирование.

На практике это означает почти всегда, что весь код шаблонов должен быть доступен в заголовке с шаблоном,
и код быть объявлен как inline (возможно, неявно).

Т.е. Шаблоны ДОЛЖНЫ БЫТЬ ВСЕ В ЗАГОЛОВОЧНЫХ ФАЙЛАХ , и включаться во все исходные модули
(если конечно шаблон не используется только в одном модуле).

Кроме включения исходного кода, в С++ пока нет другого способа разделять определения шаблонов между исходными модулями.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39453926
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLВ h и cpp -файлы добавил:
Код: plaintext
1.
#include <QString>



Не помогло.

ЭТо нужно добавить только в исходный модуль, где ты инстанциируешь шаблон с QString.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39453957
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivШаблоны ДОЛЖНЫ БЫТЬ ВСЕ В ЗАГОЛОВОЧНЫХ ФАЙЛАХ , и включаться во все исходные модули
(если конечно шаблон не используется только в одном модуле).

Кроме включения исходного кода, в С++ пока нет другого способа разделять определения шаблонов между исходными модулями.

Спасибо! Перетащил все из cpp- файла шаблона в h- файл шаблона и все взлетело.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454019
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Теперь проблема в другом месте :)

Класс содержит либо массив строк, либо массив структур, в которых лежит строка:
Код: plaintext
1.
std::vector<Type> Data;



Поэтому при вызове функции, которая принимает строку появляется ошибка:
Код: plaintext
1.
2.
3.
4.
5.
template <class Type>
void task<Type>::run()
{
    PostEvent(TypeEvent_InsertInListWidget, Data[0]); //ТУТ ОШИБКА!
}



Попытался написать так:
Код: plaintext
1.
2.
if(typeid(Type) == typeid(QString) Information = Data[0];
else Information = Data[0].Information; //ТУТ ОШИБКА!



Тоже получил ошибку:
Код: plaintext
ошибка: ‘__gnu_cxx::__alloc_traits<std::allocator<QString> >::value_type {aka class QString}’ has no member named ‘Information’.

Попробовал сделать явную перегрузку:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <>
void task<QString>::run()
{ //ТУТ ОШИБКА!
  PostEvent(TypeEvent_InsertInListWidget, Data[0].Information);
}

template <class Type>
void task<Type>::run()
{
    PostEvent(TypeEvent_InsertInListWidget, Data[0]);
}



Получил ошибку:
Код: plaintext
ошибка: multiple definition of `MyLib::task<QString>::run()'

Как выкрутиться?
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454056
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ошибся при копипасте. Последний код правильно так:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <>
void task<QString>::run()
{ //ТУТ ОШИБКА!
  PostEvent(TypeEvent_InsertInListWidget, Data[0]);
}

template <class Type>
void task<Type>::run()
{
    PostEvent(TypeEvent_InsertInListWidget, Data[0].Information);
}
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454111
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLТеперь проблема в другом месте :)

Класс содержит либо массив строк, либо массив структур, в которых лежит строка:
Поэтому при вызове функции, которая принимает строку появляется ошибка:


Как выкрутиться?

На сколько я понял, будет достаточно у этого класса/структуры определить оператор преобразования к типу строки, которая тебе нужна.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454117
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivНа сколько я понял, будет достаточно у этого класса/структуры определить оператор преобразования к типу строки, которая тебе нужна.

Спасибо, за помощь. Да, именно это и нужно. Но все те же ошибки тогда вылезут при реализации этого чудесного оператора. Надо каким-то образом при различных типах данных выполнить различный код:

Код: plaintext
1.
2.
if(typeid(Type) == typeid(QString)) Information = Data[0];
else Information = Data[0].Information; //ТУТ ОШИБКА!
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454120
Фотография NekZ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQL
Код: plaintext
1.
2.
if(typeid(Type) == typeid(QString)) Information = Data[0];
else Information = Data[0].Information; //ТУТ ОШИБКА!


Эт Вам в Python/PyQt, батенька, надо идти.
Тут ты либо пишешь специализации для каждого типа, либо используешь if constexpr , если он у тебя доступен.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454131
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
NekZЭт Вам в Python/PyQt, батенька, надо идти.
Тут ты либо пишешь специализации для каждого типа, либо используешь if constexpr , если он у тебя доступен.

Так и специализацию пробовал делать (если я правильно понимаю этот термин):
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <>
void task<QString>::run()
{ //ТУТ ОШИБКА!
  PostEvent(TypeEvent_InsertInListWidget, Data[0].Information);
}

template <class Type>
void task<Type>::run()
{
    PostEvent(TypeEvent_InsertInListWidget, Data[0]);
}



Код: plaintext
ошибка: multiple definition of `MyLib::task<QString>::run()'
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454133
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Опять ошибся при копипасте :)

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
template <>
void task<QString>::run()
{ //ТУТ ОШИБКА!
  PostEvent(TypeEvent_InsertInListWidget, Data[0]);
}

template <class Type>
void task<Type>::run()
{
    PostEvent(TypeEvent_InsertInListWidget, Data[0].Information);
}
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454412
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем спасибо! Заработало при использовании ключевого слова inline в определении специализированного и шаблонного метода.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39454850
ermak.nn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv,

Можно через template instantiation. Шаблонный класс будет доступен тогда только для определенных типов.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39455529
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ermak.nnMasterZiv,

Можно через template instantiation. Шаблонный класс будет доступен тогда только для определенных типов.

Можно то оно можно, только ЧТО?
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39456918
ermak.nn
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZiv, забыл вставить цитату. Я про это говорил.
MasterZivAlekseySQLnamespace MyLib
{
template <class Type> class task_manager : public QThreadPool
{
...

Почему???

Шаблоны ДОЛЖНЫ БЫТЬ ВСЕ В ЗАГОЛОВОЧНЫХ ФАЙЛАХ , и включаться во все исходные модули
(если конечно шаблон не используется только в одном модуле).

Кроме включения исходного кода, в С++ пока нет другого способа разделять определения шаблонов между исходными модулями.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39635807
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
MasterZivШаблоны ДОЛЖНЫ БЫТЬ ВСЕ В ЗАГОЛОВОЧНЫХ ФАЙЛАХ , и включаться во все исходные модули
(если конечно шаблон не используется только в одном модуле).

Кроме включения исходного кода, в С++ пока нет другого способа разделять определения шаблонов между исходными модулями.

Тут в первом ответе предлагается способ написать определение шаблонного метода в cpp- файле. Мне нравится этот подход, поскольку h-файл уменьшается и с ним можно работать как с интерфейсом (не лазия по огромному файлу в поисках нужной функции). Какие подводные камни у этого подхода?
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39635821
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlekseySQL Тут в первом ответе предлагается способ написать определение шаблонного метода в cpp- файле. Мне нравится этот подход, поскольку h-файл уменьшается и с ним можно работать как с интерфейсом (не лазия по огромному файлу в поисках нужной функции). Какие подводные камни у этого подхода?

Балин, тут реализация должна быть в месте использования... Не подходит этот метод.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39635846
AlekseySQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть какие- то хитрые способы, чтобы все- таки реализацию методов шаблонного класса вытащить в cpp- файл?
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39635894
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLЕсть какие- то хитрые способы, чтобы все- таки реализацию методов шаблонного класса вытащить в cpp- файл?
Есть - явное инстанцирование шаблона в том .cpp где тело шаблона.
Это делается для каждого типа с которым шаблон используется. (Линкер подскажет )

Читайте про explicit instatiation http://en.cppreference.com/w/cpp/language/class_template#Explicit_instantiation
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39636057
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLЕсть какие- то хитрые способы, чтобы все- таки реализацию методов шаблонного класса вытащить в cpp- файл?

Ты их можешь поместить в .cpp, но только если эти шаблоны будут использоваться только в этом CPP.
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39636481
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlekseySQLЕсть какие- то хитрые способы, чтобы все- таки реализацию методов шаблонного класса вытащить в cpp- файл?1. Исключить этот cpp-файл из сборки
2. Добавить #include "a.cpp" в хвост a.h
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39636734
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
CEMbAlekseySQLЕсть какие- то хитрые способы, чтобы все- таки реализацию методов шаблонного класса вытащить в cpp- файл?1. Исключить этот cpp-файл из сборки
2. Добавить #include "a.cpp" в хвост a.h


Ойойой...
Тогда надо уже и переименовать его в *.inl
...
Рейтинг: 0 / 0
Не видит реализации класса
    #39637085
Фотография CEMb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
MasterZivОйойой...необычные вопросы - необычные ответы
MasterZivТогда надо уже и переименовать его в *.inlда, пожалуй, можно даже не в inl, а в какой-нибудь tpp? Чтоб по смыслу.
...
Рейтинг: 0 / 0
26 сообщений из 26, показаны все 2 страниц
Форумы / C++ [игнор отключен] [закрыт для гостей] / Не видит реализации класса
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]