Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 25.10.2013, 18:36   #1
valeologiya
Пользователь
 
Регистрация: 07.07.2009
Сообщений: 37
По умолчанию Программа с шаблонами, ошибка компиляции

Собственно код:
Код:
#include <QFile>
#include <QString>
#include "devices.h"
#include "ca737decoder.h"
#include "cPRVdecoder.h"

int main(int argc, char *argv[])
{
    char help_1[] = "--help";
    char help_2[] = "-h";

    int device = getDevid(argv[1]);
    printf("\nDevice to decode: %s\n",getDevname(device).toAscii().data());

    CPRVDecoder     prv_decoder(argv[2],argv[3]);
    Ca737Decoder<12> a737_decoder12(argv[2],argv[3]);
    Ca737Decoder<> a737_decoder(argv[2],argv[3]);

    switch(device)
    {
        case A_737:
        a737_decoder.beginDecode();
        break;
        case SPRA:
        a737_decoder12.beginDecode();
        break;
        case PRV:
        prv_decoder.beginDecode();
        break;
        case PRO:
        prv_decoder.beginDecode(12);
        break;
    default:
        break;
    }    
    return 0;
}
Код:
#ifndef CA737DECODER_H
#define CA737DECODER_H

#include <QFile>
#include <QString>

template <int nChans = 24> class Ca737Decoder
{
public:
    Ca737Decoder(QString,QString);
    int beginDecode();
private:
    QFile* file;
    FILE*  pFile;
    bool    cantDecode;
    QString filePath_src;
    QString filePath_dst;
    quint16 CLC_checksum(const quint8* ptr, quint16 size);
};
#endif // CA737DECODER_H
Ругается на шаблонный класс. Выдает ошибки:
Цитата:
main.cpp:40: ошибка: undefined reference to `Ca737Decoder<12>::Ca737Decoder(QSt ring, QString)'
main.cpp:41: ошибка: undefined reference to `Ca737Decoder<24>::Ca737Decoder(QSt ring, QString)'
main.cpp:47: ошибка: undefined reference to `Ca737Decoder<24>::beginDecode()'
main.cpp:51: ошибка: undefined reference to `Ca737Decoder<12>::beginDecode()'
Что не так?
valeologiya вне форума Ответить с цитированием
Старый 25.10.2013, 20:18   #2
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

А где методы Ca737Decoder?
Они объявлены но их нигде нет.
waleri вне форума Ответить с цитированием
Старый 25.10.2013, 20:19   #3
Ezhik Kihze
Форумчанин
 
Регистрация: 24.12.2012
Сообщений: 639
По умолчанию

Ну объявление то вы написали... а реализацию кто будет писать?
ICQ: 677936656 Gmail: ekEmbed@gmail.com
Ezhik Kihze вне форума Ответить с цитированием
Старый 27.10.2013, 17:11   #4
valeologiya
Пользователь
 
Регистрация: 07.07.2009
Сообщений: 37
По умолчанию

Цитата:
Сообщение от Ezhik Kihze Посмотреть сообщение
Ну объявление то вы написали... а реализацию кто будет писать?
Цитата:
А где методы Ca737Decoder?
Они объявлены но их нигде нет.
Конечно, они есть, просто чтобы не захламлять сообщение я их не написал. Видимо, это сбило с толку. Простите. Дополняю кодом файла ca737decoder.cpp

Код:
#include "ca737decoder.h"
#include <QDebug>
#include <QByteArray>

template <int nChans> Ca737Decoder<nChans>::Ca737Decoder(QString filepath_sr, QString filepath_ds)
{
    filePath_src = filepath_sr;
    filePath_dst = filepath_ds;
    cantDecode = false;
    file = new QFile(filePath_src);
    if(!file->exists())
    {
        printf("Error: %s does not exist.\n", filePath_src.toAscii().data());
        cantDecode = true;
        return;
    }
}

template <int nChans> quint16 Ca737Decoder<nChans>::CLC_checksum(const quint8* ptr, quint16 size)
{
    quint16 summ = 0;
    int i = 0;
    while(i < size)
    {
        summ += *ptr++;
        i++;
    }
    return summ;
}

template <int nChans> int Ca737Decoder<nChans>::beginDecode()
{
    if(cantDecode)
    {
        printf("\nThere was error's in initialization. Decoding aborted.\n");
        return -1;
    }
    printf("Start decoding...\n");
    quint16 preambule; 
//...

}
valeologiya вне форума Ответить с цитированием
Старый 27.10.2013, 17:13   #5
valeologiya
Пользователь
 
Регистрация: 07.07.2009
Сообщений: 37
По умолчанию

Streamdecoder.pro
Код:
#-------------------------------------------------
#
# Project created by QtCreator 2013-02-21T12:10:33
#
#-------------------------------------------------

QT       += core

QT       -= gui

TARGET = StreamDecoder
CONFIG   += console
CONFIG   -= app_bundle

TEMPLATE = app


SOURCES += main.cpp \
    ca737decoder.cpp \
    cPRVdecoder.cpp

HEADERS += \
    devices.h \
    ca737decoder.h \
    cPRVdecoder.h
valeologiya вне форума Ответить с цитированием
Старый 27.10.2013, 18:05   #6
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Очень распространенная ошибка.

Как ты думаешь, в какой момент будет инстанцировано определение шаблона?
still_alive вне форума Ответить с цитированием
Старый 27.10.2013, 18:12   #7
valeologiya
Пользователь
 
Регистрация: 07.07.2009
Сообщений: 37
По умолчанию

Цитата:
Сообщение от still_alive Посмотреть сообщение
Очень распространенная ошибка.

Как ты думаешь, в какой момент будет инстанцировано определение шаблона?
Не задумывался... Полез в книгу.
valeologiya вне форума Ответить с цитированием
Старый 27.10.2013, 18:17   #8
valeologiya
Пользователь
 
Регистрация: 07.07.2009
Сообщений: 37
По умолчанию

still_alive,
В книге не нашел. Я так предполагаю что сразу перед вызовом конструктора.

Код:
Ca737Decoder<12> a737_decoder12(argv[2],argv[3]);
Ca737Decoder<> a737_decoder(argv[2],argv[3]);
valeologiya вне форума Ответить с цитированием
Старый 27.10.2013, 18:38   #9
still_alive
Great Code Monkey
Форумчанин
 
Аватар для still_alive
 
Регистрация: 09.08.2007
Сообщений: 533
По умолчанию

Специализации шаблона могут быть инстанцированы только тогда, когда есть
1) аргументы шаблона
2) определение шаблона

Мы компилируем единицу трансляции, в которую входит мэйн и хедер декодера. Ты прав, думая, что инстанцирование должно быть там, где нужно полное определение класса. Но в точках Ca373Decoder<12>, Ca737Decoder<> нам доступны только аргументы шаблона, но не его определение, которое лежит в cpp-файле, который не входит в эту единицу трансляции. Поэтому по факту инстанцирования специализации не происходит. Компилятор ставит просто заглушку, надеясь, что линковщик потом все разрулит.
Потом мы компилим другую единицу трансляции, куда входит cpp-файл. Там наоборот, доступны только определения, но нет аргументов и компилятор не знает поэтому, что ему надо что-то инстанцировать. Опять ничего не происходит.
Потом линковщик смотрит - вызовы функций-членов шаблона есть, а их реализации нет. Вот и ругается.

Как думаешь, как проблема решается?
still_alive вне форума Ответить с цитированием
Старый 27.10.2013, 21:52   #10
valeologiya
Пользователь
 
Регистрация: 07.07.2009
Сообщений: 37
По умолчанию

Спасибо, still_alive. У меня до ушей растянулась улыбка, когда я понял почему не работает. Нужно просто в файле проекта переставить местами main.cpp и сa737decoder.cpp.
valeologiya вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Проблема с шаблонами. Программа не компилирует. Даша1046 Помощь студентам 2 03.07.2013 19:53
Ошибка компиляции Selean Общие вопросы C/C++ 2 26.03.2013 08:18
Ошибка работы программы. Работа с библиотекой STL и шаблонами. С ++ Vasyl'eva Помощь студентам 1 25.12.2011 18:39
Программа для отправки писем (ошибка компиляции) Ёжик в тумане Работа с сетью в Delphi 2 22.10.2011 12:58
C++ ошибка компиляции Seil_29 Помощь студентам 9 20.12.2009 22:23