Russian Qt Forum
Ноябрь 18, 2024, 06:34 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: STL шаблон Ошибка С2019  (Прочитано 3365 раз)
Hrundel
Гость
« : Декабрь 14, 2013, 00:20 »

Всем привет,

Наконец-то приступил к изучению шаблонов. Решил написать первый опус.
Цель такая:

Код
C++ (Qt)
do{edit(loop.query(container,loop.counter()))}while(loop.isStoped());

Просто и элегантно!

Написал вот так:

Заголовок:
Код
C++ (Qt)
#ifndef LOOP_H
#define LOOP_H
 
#include <stddef.h>
#include <QVector>
#include <QObject>
 
template<typename T>
class Loop
{  
   public:
       Loop();
       virtual ~Loop(){}
 
       T  query(QVector<T> incomming, int i);
       T  query(QList<T> incomming, int i);
       int counter();
       bool isStoped();
 
   private:
       int count;
       int stoped;
};
 
#endif // LOOP_H

Ресурс:
Код
C++ (Qt)
#include "loop.h"
 
template<typename T>
Loop<T>::Loop():
   count(0)
 , stoped(false)
{
}
 
template<typename T>
T Loop<T>::query(QVector<T> incomming, int i)
{
   if(!stoped) return incomming.at(i);
   if(i+1 >= incomming.size()) stoped = true;
}
 
template<typename T>
T Loop<T>::query(QList<T> incomming, int i)
{
   if(!stoped) return incomming.at(i);
   if(i+1 >= incomming.size()) stoped = true;
}
 
template<typename T>
int Loop<T>::counter()
{
   count++;
}
 
template<typename T>
bool Loop<T>::isStoped()
{
   return stoped;
}
 

Дальше пытаюсь использовать:

Код
C++ (Qt)
   list << "First" << "Second" << "Third" << "Forth" << "Firth" ;
 
   Loop<QString> loop;
 
   do{edit(loop.query(list,loop.counter()));} while(loop.isStoped());

Компилятор пишет:

Цитировать
mainwindow.obj:-1: error: LNK2019: unresolved external symbol "public: bool __thiscall Loop<class QString>::isStoped(void)" (?isStoped@?$Loop@VQString@@@@QAE_NXZ) referenced in function "public: __thiscall MainWindow::MainWindow(class QWidget *)" (??0MainWindow@@QAE@PAVQWidget@@@Z)

Не понимаю причину. Почему нет доступа линкера?
Записан
kambala
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4747



Просмотр профиля WWW
« Ответ #1 : Декабрь 14, 2013, 00:58 »

реализации шаблонов должны находиться в заголовочном файле.
Цитировать
Просто и элегантно!
особенно в виду отсутствия пробелов Улыбающийся
Записан

Изучением C++ вымощена дорога в Qt.

UTF-8 has been around since 1993 and Unicode 2.0 since 1996; if you have created any 8-bit character content since 1996 in anything other than UTF-8, then I hate you. © Matt Gallagher
Old
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 4350



Просмотр профиля
« Ответ #2 : Декабрь 14, 2013, 04:42 »

В таком виде stopped никогда не станет true.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #3 : Декабрь 14, 2013, 10:11 »

Код
C++ (Qt)
       T  query(QVector<T> incomming, int i);
       T  query(QList<T> incomming, int i);
 
Подавать контейнеры по значению вообще плохо, многие считают это грубой ошибкой, безграмотностью.

Ресурс:
Если имеется ввиду cpp файл, то да, не слинкует. При "инстанциировании" тела template должны быть видимы, поэтому их обычно пишут в h файле - или включают .cpp файл в .h файл. Часто говорят "должны быть в той же единице трансляции".
Записан
VPS
Гость
« Ответ #4 : Декабрь 14, 2013, 17:38 »

Если не учитывать логику работы Вашего кода, то добавлю ещё, что вместо двух методов
Код:
T  query(QVector<T> incomming, int i);
T  query(QList<T> incomming, int i);
с одинаковым телом можно написать один шаблонный.
Записан
_Bers
Бывалый
*****
Offline Offline

Сообщений: 486


Просмотр профиля
« Ответ #5 : Декабрь 14, 2013, 21:37 »

1. Тела функций шаблонов должны быть определены там же, где и объявлены (в хэдерах)

2.

Код:
template<typename T>
T Loop<T>::query(QList<T> incomming, int i)
{
    if(!stoped) return incomming.at(i);
    if(i+1 >= incomming.size()) stoped = true;

    //<--- UB. возвращается мусор.
}

3.

Код:
template<typename T>
int Loop<T>::counter()
{
    count++;
    //<--- UB. возвращается мусор.
}

4. В качестве типа, определяющего количество используется int. Признак неграмотности. Используйте size_t

----
Хотя это спорный момент. Ибо используется он в качестве typedef QVector::size_type
Лучше сразу использовать QVector::size_type для индексов, ибо если верить документации, он в куте как раз таки int
« Последнее редактирование: Декабрь 14, 2013, 21:43 от _Bers » Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.212 секунд. Запросов: 22.