Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> шаблонный аргумент шаблона, проблемы перехода с VS 2003 на VS 2008 
V
    Опции темы
Earnest
Дата 20.8.2010, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Допустим, есть шаблонный класс обобщенной полилинии:
Код

template <class _Tp, template<class,class> class _Cont = std::vector, class _Alloc = std::allocator<_Tp> >    
class poly_base: public _Cont <_Tp, _Alloc>
{
   ...
};

Здесь _Tp - тип вершины, а _Cont - контейнер, в котором вершины хранятся, по умолчанию - вектор.

Дальше, объявляем специальный контейнер:
Код

template <class _Vert, class _Alloc = std::allocator<_Vert> > 
class CVcdPolyRef
{
   ...
};

и объявляем специализированный шаблон полилинии с этим контейнером:
Код

template <class _Vert>
class CVcdPolyBase: public poly_base <_Vert, CVcdPolyRef>
{
};

Пока все хорошо. Траблы начинаются, когда (внутри объявления класса) я пытаюся написать 
   typedef poly_base <_Vert, CVcdPolyRef> base_class;

На эту строку компилятор ругается так: 
error C3200: 'CVcdPolyRef<_Vert,_Alloc>' : invalid template argument for template parameter '_Cont', expected a class template
Можно подумать, я ему не template подсовываю...
В 2003 это все нормально компилируется и работает...

Вопрос, как обойти. base_class нужен для 2 вещей: во-первых, объявить в классе производные типы (там их море). Но здесь я выкрутилась. 
А вот как вызвать конструктор базового класса из конструктора шаблона CVcdPolyBase (если мне нужен конструктор с параметром)?
Прямая подстановка вместо base_class - poly_base <_Vert, CVcdPolyRef> - не катит - та же ошибка C3200.

Понятно, что base_class, который я пытаюсь объявить, не совсем тип, а все-таки шаблон. В 2008 ужесточили синтаксис, подогнав ближе к стандарту, тоже понятно. Но что делать-то в данной ситуации? Есть идеи?

Т.е. я, конечно, выкрутилась, но очень через ж... Хотелось бы понять, как правильно.


--------------------
...
PM   Вверх
azesmcar
Дата 20.8.2010, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Код

template <class _Tp, template<class,class> class _Cont = std::vector, class _Alloc = std::allocator<_Tp> >    
class poly_base: public _Cont <_Tp, _Alloc>
{
protected:
    typedef poly_base <_Tp, _Cont, _Alloc> this_type;
};

может так?

подозреваю, что это все таки проблема в студии, ибо ведет она себя мягко говоря некорректно.

тот же typedef где нибудь в другом месте замечательно компилируется
Код

int main()
{
   typedef poly_base<Vert, CVcdPolyRef> base_class;
}

если заменить CVcdPolyRef на что либо другоето код снова компилируется
скажем так
Код

template <typename Vert>
class CVcdPolyBase: public poly_base <Vert, CVcdPolyRef>
{
    typedef poly_base<Vert, std::list> base_class;
};


а теперь кое что поинтереснее
Код

namespace trick {
    template <class Vert, class Alloc = std::allocator<Vert> > 
    class CVcdPolyRef
    {
    };
}

template <typename Vert>
class CVcdPolyBase: public poly_base <Vert, trick::CVcdPolyRef>
{
    typedef poly_base<Vert, trick::CVcdPolyRef> this_type;
};

попробуй вот так smile 

или в конце концов вот так
Код

template <class Vert, class Alloc = std::allocator<Vert> > 
class CVcdPolyRef
{
};

template <typename Vert>
class CVcdPolyBase: public poly_base <Vert, CVcdPolyRef>
{
    typedef poly_base<Vert, ::CVcdPolyRef> this_type;
};


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

Это сообщение отредактировал(а) azesmcar - 20.8.2010, 16:23
PM   Вверх
Earnest
Дата 20.8.2010, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(azesmcar @  20.8.2010,  16:56 Найти цитируемый пост)
но в любом случае я бы сделал так, как показал в начале поста, у класса может быть много наследников, зачем в каждом из них определять базовый тип, пусть он будет определен в базовом.

Не поняла, в начале - это
 typedef poly_base <_Tp, _Cont, _Alloc> this_type;
?
Но по-моему, это неправильно - _Alloc это аргумент контейнера, а не третий аргумент шаблона...
Остальное сейчас попробую, хотя что-то похожее вроде пробовала (с namespace).

Добавлено через 5 минут и 59 секунд
Цитата(azesmcar @  20.8.2010,  16:56 Найти цитируемый пост)
   typedef poly_base<Vert, ::CVcdPolyRef> this_type;

Вау! Я кое-что опустила вначале - вся эта хрень сама по себе находится в своем пространстве имен - Vcd.
Как только ставлю Vcd::CVcdPolyRef - компилируется! Убираю - фиг вам.
Все-таки глюк..
Спасибо azesmcar! Пошла выковыривать обходы через ж... 


--------------------
...
PM   Вверх
azesmcar
Дата 20.8.2010, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Earnest @  20.8.2010,  16:38 Найти цитируемый пост)
Но по-моему, это неправильно - _Alloc это аргумент контейнера, а не третий аргумент шаблона...

Но ведь класс base принимает 3 шаблонных параметра - три и передаем в typedef-е, конечно, можно и два, но тогда третий будет всегда по умолчанию.

Цитата(Earnest @  20.8.2010,  16:38 Найти цитируемый пост)
Вау! Я кое-что опустила вначале - вся эта хрень сама по себе находится в своем пространстве имен - Vcd.
Как только ставлю Vcd::CVcdPolyRef - компилируется! Убираю - фиг вам.
Все-таки глюк..

Да, я так понял студия тут путается, и подставляет в аргумент шаблона вместо имени класса что-то другое..но вот что? Путается она вот тут
Цитата

template <typename Vert>
class CVcdPolyBase: public poly_base <Vert, CVcdPolyRef>
{
    typedef poly_base<Vert, CVcdPolyRef> this_type;
};

 smile 
Цитата(Earnest @  20.8.2010,  16:38 Найти цитируемый пост)
Спасибо azesmcar! Пошла выковыривать обходы через ж...  

Пожалуйста smile 

Кстати, не стоит так называть переменные/типы итд...это зарезервированные имена
Цитата

17.4.3.1 Reserved names

If the program declares or defines a name in a context where it is reserved, other than as explicitly allowed
by this clause, the behavior is undefined.
...
Each name that contains a double underscore (_ _) or begins with an underscore followed by an uppercase
letter (2.11) is reserved to the implementation for any use.


Это сообщение отредактировал(а) azesmcar - 20.8.2010, 17:45
PM   Вверх
Earnest
Дата 20.8.2010, 19:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(azesmcar @  20.8.2010,  18:31 Найти цитируемый пост)
Но ведь класс base принимает 3 шаблонных параметра -

А, да, действительно, об аллокаторе я как-то забыла... Он и всунут-то туда был, чтобы вектор можно было использовать...
Цитата(azesmcar @  20.8.2010,  18:31 Найти цитируемый пост)
Кстати, не стоит так называть переменные/типы итд...это зарезервированные имена

так вроде у меня нет двух underscore, и не начинается с них
Цитата(azesmcar @  20.8.2010,  18:31 Найти цитируемый пост)
подставляет в аргумент шаблона вместо имени класса что-то другое..но вот что?

Действительно, вопрос интересный - CVcdPolyRef нигде не дублируется, проверяла.
Обидно, что глюк привнесенный - ведь в 2003 все нормально компилировалось. Переписали, блин, компилятор. Прямо как мы - одну ошибку правим, 2 новых добавляем...



--------------------
...
PM   Вверх
azesmcar
Дата 20.8.2010, 19:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 81
Всего: 211



Цитата(Earnest @  20.8.2010,  19:04 Найти цитируемый пост)
так вроде у меня нет двух underscore, и не начинается с них

Я про эти
Цитата(Earnest @  20.8.2010,  15:39 Найти цитируемый пост)
class _Tp

Цитата(Earnest @  20.8.2010,  15:39 Найти цитируемый пост)
_Alloc

Цитата(Earnest @  20.8.2010,  15:39 Найти цитируемый пост)
_Tp

Цитата(Earnest @  20.8.2010,  15:39 Найти цитируемый пост)
_Cont

имелось ввиду
Цитата(azesmcar @  20.8.2010,  17:31 Найти цитируемый пост)
or begins with an underscore followed by an uppercase

т.е. имена, которые содержат двойное подчеркивание или начинаются с подчеркивания и заглавной буквы.
У Саттера в More Exceptional C++ была глава посвященная этому, сейчас попробую найти.

добавлено
По поводу ГЛАВЫ я конечно погорячился, но достаточно красочно описано smile 
Цитата

Underhanded Names

There's one mechanical problem I haven't yet covered. This problem first rears its ugly, unshaven, and unshampooed head in the following line:

Код

enum uniontype {NONE,_INT,_LIST,_STRING};


Never, ever, ever create names that begin with an underscore or contain a double underscore; they're reserved for your compiler and standard library vendor's exclusive use, so that they have names that they can use without tromping on your code. Tromp on their names, and their names might just tromp back on you! (The more specific rule is that any name with a double underscore anywhere in it __like__this or that starts with an underscore and a capital letter _LikeThis is reserved. You can remember that rule if you like, but it's a bit easier to just avoid both leading underscores and double underscores entirely.) 

http://www.gotw.ca/gotw/085.htm

Цитата(Earnest @  20.8.2010,  19:04 Найти цитируемый пост)
Обидно, что глюк привнесенный - ведь в 2003 все нормально компилировалось. Переписали, блин, компилятор. Прямо как мы - одну ошибку правим, 2 новых добавляем...

В 2010-ой тоже самое. 

Это сообщение отредактировал(а) azesmcar - 20.8.2010, 19:52
PM   Вверх
Earnest
Дата 23.8.2010, 19:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(azesmcar @  20.8.2010,  20:41 Найти цитируемый пост)
Я про эти

Да, действительно... но это аргументы шаблона, и их действие неглубоко, и код довольно старый, давно живут.
Мне там столько всего править для перехода, что то, что нормально компилируется, трогать не буду.
Кстати, мелкософт может захапать под стандартное и без всякого подчеркивания имена - помнится, при переходе 6 -> 2003 сталкивалась, так что не угадаешь. Да и не такая это проблема, по крайней мере, чтобы так эмоционально как Саттер описывать...



--------------------
...
PM   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0719 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.