Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Переполнение стека. Помогите!

64K
06 мая 2011 года
LGFox
10 / / 26.02.2011
Добрый день. Пишу/изучаю шаблоны C++. У меня есть код шаблонов классов. Это только часть кода - объявления. С классом id_one_table все хорошо. Код компилируется, но при запуске программа валится с ошибкой переполнения стека. Отладка не возможна. Я собственно, хотел бы чтобы вы глазами профессионалов посмотрели на эти объявления - может где рекурсия есть или что ещё...
P.S. Это код объявления шаблона класса id_node (наследника шаблона класса id_node_com) и две его конкретные специализации для параметра-типа (id_one_table) и параметра-шаблона (id_node<id_one_table>)...
Код:
template <class C> class id_node: public id_node_com<C>
{
    public:
        id_node(UnicodeString table_name, UnicodeString p_id,  UnicodeString p_table, bool inf_store=false, UnicodeString f_names="", UnicodeString f_one_names="", UnicodeString f_two_names="", UnicodeString f_one_1_names="", UnicodeString f_one_2_names="");
};

template <> class id_node<id_one_table>: public id_node_com<id_one_table>
{
    public:
        id_node(UnicodeString table_name, UnicodeString p_id,  UnicodeString p_table, bool inf_store=false, UnicodeString f_names="", UnicodeString f_one_names="", UnicodeString f_two_names="", UnicodeString f_one_1_names="", UnicodeString f_one_2_names="");
        void load(bool def=false);
};

template <> class id_node<id_node<id_one_table> >: public id_node_com<id_node<id_one_table> >
{
    public:
        id_node(UnicodeString table_name, UnicodeString p_id,  UnicodeString p_table, bool inf_store=false, UnicodeString f_names="", UnicodeString f_one_names="", UnicodeString f_two_names="", UnicodeString f_one_1_names="", UnicodeString f_one_2_names="");
        void load(bool def=false);
};
2.1K
06 мая 2011 года
Norgat
452 / / 12.08.2009
Приведи код в читаемое состояние. Читать это месиво сейчас невозможно.
277
06 мая 2011 года
arrjj
1.7K / / 26.01.2011
Покажи объявление id_one_table
64K
07 мая 2011 года
LGFox
10 / / 26.02.2011
Если я убираю специализации шаблона класса id_node_com по параметру-типу (id_one_table) и параметру-шаблону (id_node<id_one_table>), то переполнение исчезает. Специализации шаблона мне нужны, так как в классе есть методы, создающие объекты с разными конструкторами и при инстанцировании компилятор ругается, на отсутствие подобных конструкторов.

Может быть вы подскажете как в шаблоне:
Цитата:
template <class T> class id_node: public id_node_com<T>


организовать создание экземпляров класса T, если они могут иметь РАЗНЫЕ конструкторы?

Хм. Странно, но если меняю объявление

Цитата:
template <> class id_node<id_node<id_one_table> >: public id_node_com<id_node<id_one_table> >
{
public:
...
};


например на

Цитата:
template <> class id_node<id_node<int> >: public id_node_com<id_node<int> >
{
public:
...
};


то все запускается нормально...

Цитата: arrjj
Покажи объявление id_one_table


Код:
namespace id_memorandum_types
{
    typedef std::vector<UnicodeString *> StrTab;
    typedef std::deque<UnicodeString> StrQueue;
    typedef std::pair<int, id_memorandum_types::StrTab *> Id_Obj;
};

class id_memorandum
{
    protected:
        int id_count;
        int field_count;
        UnicodeString field_names;
        bool information_store;
        std::map<int, id_memorandum_types::StrTab *> ids;
    public:
        id_memorandum(bool inf_store=false, UnicodeString f_names="");
        bool add_id(int id, id_memorandum_types::StrTab *id_string);
        bool del_id(int index);
        id_memorandum_types::Id_Obj get_id(int index);
        id_memorandum_types::Id_Obj find_id(int id);
        int count();
};

class id_one_table:public id_memorandum
{
    protected:
        UnicodeString table,id_name,parent_id,parent_table,parent_id_name;
    public:
        id_one_table(UnicodeString table_name, UnicodeString p_id, UnicodeString p_table, bool inf_store=false, UnicodeString f_names="");
        bool add_record(UnicodeString fields, UnicodeString values);
        sh_core::query_table *get_record(int index, UnicodeString fields);
        bool set_record(int index, UnicodeString fields_and_values);
        bool del_record(int index);
        void empty();
        void load(bool del=false);
};
64K
07 мая 2011 года
LGFox
10 / / 26.02.2011
Цитата: Norgat
Приведи код в читаемое состояние. Читать это месиво сейчас невозможно.


Вот минимальный код с подобной ошибкой (компилировал на "Embarcadero C++ Builder 2010 XE 15.0.3890.34076"): при запуске это рушится с ошибкой переполнения стека... (на Visual C++ не компилируется с ошибкой
"123321.cpp(21): error C2244: BigErrorHere<int>::{ctor}: не удается сопоставить определение функции существующему объявлению
определение
'BigErrorHere<int>::BigErrorHere(char)'
существующие объявления
'BigErrorHere<int>::BigErrorHere(const BigErrorHere<int> &)'
'BigErrorHere<int>::BigErrorHere(char)'" - полагаю здесь где-то explicit использовать надо? Объявление всех конструкторов с explicit результата не принесло...)

Код:
template<class T> class BigErrorHere
{
    public:
    BigErrorHere(char hello) {};
};

template<> class BigErrorHere<int>
{
    public:
    BigErrorHere(char hello);
};

template<class T> BigErrorHere<int>::BigErrorHere(char hello)
{};

BigErrorHere<int> Bug('X');


Причем нижеприведенный код запускается нормально...
Код:
template<class T> class BigErrorHere
{
    public:
    BigErrorHere(char hello) {};
};

template<> class BigErrorHere<int>
{
    public:
    BigErrorHere(char hello) {};
};

BigErrorHere<int> Bug('X');


Эй, короче... Я так понимаю у каждого компилятора свои замуты со специализацией шаблонов. Просто сделал определение конструкторов внутри объявления класса и все заработало (explicit не помог - была все та же stack overflow). И это не смотря на то, что остальные методы я все же определяю отдельно. Кстати, компилятор Builder'a не указал на ошибку и просто вывалился со странной stackoverflow (я, дурак, полтора дня рекурсию искал) при запуске, а компилятор Visual C++ указал на ошибку. Судите о качестве компиляторов, Господа!

Ссылки по теме, может кому пригодятся...
msdn.microsoft.com - здесь говорится, что нельзя специализировать шаблон функции частично.
stackoverflow.com - а здесь парень выкрутился аналогичным способом.
64K
09 мая 2011 года
LGFox
10 / / 26.02.2011
Беру обратно слова в адрес разработчиков компиляторов. Это цитата из книги "Шаблоны С++. Справочник разработчика" Дэвида Вандевурда:
Цитата:

Чтобы специализировать шаблон класса, следует объявить класс, предварив его конструкцией template<>, и указать типы, для которых специализируется шаблон класса. Типы используются в качестве аргументов шаблона и задаются непосредственно после имени класса.
template <> class Stack<std::string>
{
void push(std::string const& elem);
...
}
Для таких специализаций любая функция-член должна определяться как "обычная" функция-член с заменой каждого включения Т специализированным типом.
void Stack<std::string>:: push(std::string const& elem)
{
elems.push_back(elem); // Добавление копии элемента в конец массива
}


Как видно из этой цитаты "бажный" кусок кода:

Код:
template<class T> class BigErrorHere
{
    public:
    BigErrorHere(char hello) {};
};

template<> class BigErrorHere<int>
{
    public:
    BigErrorHere(char hello);
};

template<class T> BigErrorHere<int>::BigErrorHere(char hello)
{};

BigErrorHere<int> Bug('X');

исправляется удалением template<class T> из объявления конструктора:
Код:
template<class T> class BigErrorHere
{
    public:
    BigErrorHere(char hello) {};
};

template<> class BigErrorHere<int>
{
    public:
    BigErrorHere(char hello);
};

BigErrorHere<int>::BigErrorHere(char hello)
{};

BigErrorHere<int> Bug('X');

Как геморройна жизнь начинающего...
14
09 мая 2011 года
Phodopus
3.3K / / 19.06.2008
Цитата: LGFox

Ссылки по теме, может кому пригодятся...
msdn.microsoft.com - здесь говорится, что нельзя специализировать шаблон функции частично.


А я не увидел у вас функций, только классы. Хотя может среди того месива кода и есть, у меня тоже глаза ломаются смотреть :)

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог