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

Ваш аккаунт

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

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

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

Локальный тип - параметр шаблона

350
04 февраля 2008 года
cheburator
589 / / 01.06.2006
Имеется такой код:
Код:
void UserThread::ProcessCommand_ListGroups ()
{
    if (!session->get_right_admin())
        throw command_exception (msg_no_rights);
    char grpname[100];
    xbShort retcode;
    struct GroupInfo
    {
        string name;
        BYTE r_admin;
        BYTE r_load;
        BYTE r_config;
    };
    list<GroupInfo> groups;
    DWORD grp_count = 0;
    {
        DataMultiLock lock (false, false, true);
        {
            xbNdx &idx = lock.get_groups_index_name();
            xbDbf &dbf = lock.get_groups_table();
            retcode = idx.GetFirstKey();
            while (retcode == XB_NO_ERROR)
            {
                if (dbf.GetField(groups_field_chd)[0] == 'Y')
                {
                    retcode = idx.GetNextKey();
                    continue;
                };
                ++grp_count;
                dbf.GetField (groups_field_name, grpname);
                XBaseWork::del_ws(grpname);
                groups.push_back (GroupInfo());
                groups.back().name = grpname;
                groups.back().r_admin = ((dbf.GetField(groups_field_r_admin)[0] == 'Y') ? 1 : 0);
                groups.back().r_load = ((dbf.GetField(groups_field_r_load)[0] == 'Y') ? 1 : 0);
                groups.back().r_config = ((dbf.GetField(groups_field_r_config)[0] == 'Y') ? 1 : 0);
                retcode = idx.GetNextKey();
            };
            if (retcode != XB_EOF)
                throw exception (xbase.GetErrorMessage(retcode));
        }
    }
    sock << ans_accepted << grp_count;
    list<GroupInfo>::const_iterator iter = groups.begin();
    list<GroupInfo>::const_iterator end_iter = groups.end();
    for (; iter != end_iter; ++iter)
        sock << (iter->name) << (iter->r_admin) << (iter->r_load) << (iter->r_config);
};

при компиляции которого в студии 2005-й выдается ошибка C1001 (внутренняя ошибка компилятора).
Потратил пол-дня, пытаясь как-то выйти из ситуации, в результате скачал Dev-cpp 4.9.9.2 и попробовал скомпилить в нем, он ругнулся на применение локального типа (struct GroupInfo) в строке
list<GroupInfo> groups;
после чего я вернулся в студию и попробовал структуру GroupInfo
вынести за пределы метода ProcessCommand_ListGroups, и код стал компилиться...
В связи с этим вопрос. Получается, локальные типы нельзя использовать как параметры шаблона???
Предположим, что так... Но ошибка начала вылезать только после реорганизации кода (я перенес некоторые функции в другие файлы, изменил названия некоторых типов, в том числе DataMultiLock раньше назывался по-другому), а до этой реорганизации все компилировалось!

Конкретный текст ошибки:
c:\program files\microsoft visual studio 8\vc\include\xmemory(145) : fatal error C1001: An internal error has occurred in the compiler.
(compiler file 'msc1.cpp', line 1392)

Строка 145 в xmemory:
 
Код:
pointer allocate(size_type _Count)
/*Это строка 145*/     {   // allocate array of _Count elements
        return (_Allocate(_Count, (pointer)0));
        }
505
04 февраля 2008 года
vAC
343 / / 28.02.2006
У меня та же ошибка вылетела.
Решил разобраться, т.к. подобное тоже когда-то случалось.
Накатил сейчас SP1 - компилиться перестал даже простейший проект :)
Нашел в инете, что для исправления бага достаточно перетащить из папки src в include файл xutility. Так и сделал - все заработало, локальные типы можно юзать. Так что, думаю, что это глюк.
3
04 февраля 2008 года
Green
4.8K / / 20.01.2000
Цитата: cheburator

В связи с этим вопрос. Получается, локальные типы нельзя использовать как параметры шаблона???


14.3.1 Template type arguments
....
2. A local type, a type with no linkage, an unnamed type or a type compounded from any of these types shall not be used as a template-argument for a template type-parameter. [Example:

 
Код:
template <class T> class X { /* ... */ };
void f()
{
    struct S { /* ... */ };
    X<S> x3;   // error: local type used as template-argument
    X<S*> x4;  // error: pointer to local type used as template-argument
}

—end example] [Note: a template type argument may be an incomplete type (3.9). ]
350
04 февраля 2008 года
cheburator
589 / / 01.06.2006
Так и думал :)
Собсно, в любом случае - глюк в компиляторе MSVC. Да еще плюс несоответствие стандарту.
505
04 февраля 2008 года
vAC
343 / / 28.02.2006
мдэ, думал 2005-я полностью отвечает стандарту...а получается что такое можно скомпилить, накатив СП1.
вот тут как раз такое обсуждается:
http://www.thescripts.com/forum/thread649683.html
350
05 февраля 2008 года
cheburator
589 / / 01.06.2006
Ну, насчет "отвечает стандарту", еще одна вещь:
 
Код:
throw std::exception ("Ашыпка");

msvc компилит, а Dev-cpp нет, говорит, что нет такого конструктора - exception (const char* const&), который есть в студии. И, соответственно, метод what() не реализован, а в студии реализован.
Вышел из положения так.
Код:
class my_exception : public std::exception
{
public:
       my_exception (const char * const &e)
       :exception(), m_what(e)
       {
       };
       const char *what() const throw()
       {
             return m_what;
       };
private:
        const char * const &m_what;
};

И еще момент.
Код:
class A
{
public:
 void B();
}

/*...*/

void A::B() throw()
// Здесь ругается
{
}

Dev-cpp ругнулся на то, что спецификации исключений не совпадают в объявлении и реализации, а студия закрывает на это глаза...
Ну, и вдогонку, еще момент...
 
Код:
// Файл a.h (непосредственно в каталоге проекта)
#include "x/b.h"

// Файл b.h (в каталоге x)
#include "x/c.h" // катит в студии, не катит в Dev-cpp
#include "c.h" // наоборот, катит в Dev-cpp, не катит в студии
// Файл c.h находится в каталоге x

В общем, студия всегда измеряет пути от проекта, а Dev-cpp - от того каталога, где находится текущий файл.
Вот такая вот кроссплатформенность :)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог