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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> инициализация статических данных 
:(
    Опции темы
zss
Дата 3.7.2006, 09:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



есть шаблонный класс

Код

template <typename T>
class Parser {
private :
    Parser (const Parser&);
    Parser& operator = (const Parser&);

protected :
    typedef std::map <T, std::string> Map;
    typedef typedef Map::const_iterator ItMap;
    static const Map map_;

public :
    Parser () {;}
    virtual ~Parser () {;}

    static T ToValue (const std::string& string);
    static std::string ToString (T value);
};



я хочу наследоваться от него и просто инициализировать map_;

например *.h
Код

enum ENUM
{
   a,
   b,
   c
   ...
}

class Some : Parser<ENUM> {};


и тогда 
*.cpp
Код

const Parser<ENUM>::Map Some::Parser::map_ = boost::assign::map_list_of(a, "a")(b, "b")(c, "c");


но
1. Говорит, что нельзя инициализировать статические члены через производный класс
2. каждый шаблон будет инстанцирован со своим статическим map_? 

например
Код

class Some1 : Parser<ENUM> {};
class Some2 : Parser<ENUM> {};
...
const Parser<ENUM>::Map Some1::Parser::map_ = boost::assign::map_list_of(a, "a")(b, "b")(c, "c");
const Parser<ENUM>::Map Some2::Parser::map_ = boost::assign::map_list_of(a, "a")(b, "b")(c, "c");


3.и как будет дело обстоять с однотипными шаблонами (тоесть инстанцированные одним типом) 

например
Код

class Some1 : Parser<ENUM1> {};
class Some2 : Parser<ENUM2> {};
...
const Parser<ENUM1>::Map Some1::Parser::map_ = boost::assign::map_list_of(a, "a")(b, "b")(c, "c");
const Parser<ENUM2>::Map Some2::Parser::map_ = boost::assign::map_list_of(a, "a")(b, "b")(c, "c");

 
PM MAIL ICQ   Вверх
slava72
Дата 3.7.2006, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.6.2006

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



т.к. map_ принадлежит Parser<ENUM> то и инициализировать нужно Parser<ENUM>::map_

соответствено, все классы порожденные от Parser<ENUM> будут разделять 1 и тот же map_, а
Parser<ENUM1>::map_ и  Parser<ENUM2>::map_ - различны 
PM MAIL   Вверх
zss
Дата 3.7.2006, 11:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



Цитата(slava72 @  3.7.2006,  11:07 Найти цитируемый пост)
соответствено, все классы порожденные от Parser<ENUM> будут разделять 1 и тот же map_, а
Parser<ENUM1>::map_ и  Parser<ENUM2>::map_ - различны  


спасибо - понятно (главное что для разных ENUM разные map_)


Цитата(slava72 @  3.7.2006,  11:07 Найти цитируемый пост)
т.к. map_ принадлежит Parser<ENUM> то и инициализировать нужно Parser<ENUM>::map_


пробовал
Код

const Parser<ENUM>::Map Some::Parser<ENUM>::map_ = ...;


таже фигня  

Это сообщение отредактировал(а) zss - 3.7.2006, 11:25
PM MAIL ICQ   Вверх
slava72
Дата 3.7.2006, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.6.2006

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



а так ?
Код

const Parser<ENUM>::Map Parser<ENUM>::map_ = ...
 

вообще то для подобных конструкций предпочитаю пользоватся typedef-ом )) 

Это сообщение отредактировал(а) slava72 - 3.7.2006, 12:06
PM MAIL   Вверх
zss
Дата 3.7.2006, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



Цитата(slava72 @  3.7.2006,  12:04 Найти цитируемый пост)
а так ?

тоже самое


Цитата(slava72 @  3.7.2006,  12:04 Найти цитируемый пост)
вообще то для подобных конструкций предпочитаю пользоватся typedef-ом )) 


Map и есть typedef
Код

    typedef std::map <T, std::string> Map;
    typedef typedef Map::const_iterator ItMap;
 
PM MAIL ICQ   Вверх
slava72
Дата 3.7.2006, 12:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.6.2006

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



Выдержка из draft-a:

Цитата

14.5.1.3 Static data members of class templates [temp.static]
1 A definition for a static data member may be provided in a namespace scope enclosing the definition of the static
member’s class template. [ Example:
template < class T > class X {
static T s;
};
template < class T > T X<T >::s = 0;


Не до конца понятно, но похоже инитить чем хочешь не получится. Обмануть можно чем то вроде:
Код

template <typename T> struct TypeOfMapInit {};

template <typename T>
std::map <T, std::string> InitMap(TypeOfMapInit<T>); 
// обявляем шаблонную функцию для инициализации

template <typename T>    
class Parser {
...
};
template<class T> const Parser<T>::Map Parser<T>::_map = InitMap(TypeOfMapInit<T>());
// инициализируем вызовом шаблонной функции

// специализируем инициализатор
template<>
std::map < ENUM, std::string>  InitMap(TypeOfMapInit< ENUM>) {
  return boost::assign::map_list_of(a, "a")(b, "b")(c, "c");
}


Что-то типа этого, но не уверен что прокатит ((

либо (для сокрытия деталей) в классе Some1 объявляем статическую функцию, возвращающюю map
(можно приватню - тогда объявляем InitMap другом), в специализации InitOfMap - вызываем эту статическую функцию. Реализация функции в .cpp

  

Это сообщение отредактировал(а) slava72 - 3.7.2006, 12:57
PM MAIL   Вверх
slava72
Дата 3.7.2006, 13:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.6.2006

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



Еще 1-н вариант (не знаю насколько удобный/удачный) в этой задаче - шаблонс с 2-мя параметрами,
при этом 2-й - указатель на функцию. Хотя не совсем ясен прототип этой функции. Компилера под рукой нет, но что-то подобное:

Код


template<class T, std::map<T> (*F)()>
class Parser {    
...    
};    
template<class T, std::map<T> (*F)()>
const Parser<T>::Map Parser<T>::_map = F();

 
PM MAIL   Вверх
zss
Дата 3.7.2006, 14:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



slava72, вот так компилится

Код

template <>
const Some::Parser<ENUM>::Map Some::Parser<ENUM>::map_ = ...


но я не совсем уверен, что это правильно

и еще не линкуется - говорит, что не видно ToString и ToValue 
PM MAIL ICQ   Вверх
slava72
Дата 3.7.2006, 15:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.6.2006

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



Если компиоится, то все нормально, по идее номальная специализация.

А ToString и ToValue похоже надо писать самому - это преобразование класса <T> в стороку и обратно. 

В .cpp:

Код

template <>
ENUM Parser<ENUM>::ToValue (const std::string& string) {
  ...
}

template <>
std::string Parser<ENUM>::ToString (ENUM value) {
  ...
}

  

Это сообщение отредактировал(а) slava72 - 3.7.2006, 15:08
PM MAIL   Вверх
zss
Дата 3.7.2006, 15:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



Цитата(slava72 @  3.7.2006,  15:06 Найти цитируемый пост)
А ToString и ToValue похоже надо писать самому - это преобразование класса <T> в стороку и обратно. 


тогда пропадает весь смысл шаблонного наследования smile
 
PM MAIL ICQ   Вверх
slava72
Дата 3.7.2006, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 22
Регистрация: 23.6.2006

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



Цитата

тогда пропадает весь смысл шаблонного наследования 


Если шаблонные функции вызываются, значит их кто-то должен написать ? smile 

Можно наложить ограничения на шаблонный параметр, например считать 
T - классом, имеющим конструктор от строки и преобразование в строку.
Или дружественные функции string ToString(const T&) или еще что нибудь.

Для этих типов пишешь обобщенную реализацию функций.
А для всех не удовлетворяющих - специализированные функции.

Опять таки вопрос - кто автор класса Parser - если ты сам, то нужно более детально продумать что и как ты хочешь сделать. А если кто-то другой, то есть что дают ... smile  
PM MAIL   Вверх
zss
Дата 3.7.2006, 15:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 708
Регистрация: 17.6.2004

Репутация: 1
Всего: 2



Цитата(slava72 @  3.7.2006,  15:37 Найти цитируемый пост)
Если шаблонные функции вызываются, значит их кто-то должен написать ?



все оказалось проще - у меня реализация была описана в *.cpp - перенес в *.h и все сварилось smile

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

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

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

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

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


 




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


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

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