Я работаю с CodeWarrior 8.3 на Macintosh и столкнулся с такой проблемой: как передать шаблон функции как параметр шаблона другой функции или класса?
Немного истории . Есть правильно работающий код:
// TList - Loki::Typelist<>
// конвертирует тип из списка типов в адрес конкретизации
// функции FunctionsOwner::Function1 этим типомtemplate <class TList, class FunctionsOwner>
struct TypeListToFunctionMap
{
void Convert(FunctionsOwner::Map& map)
{
...
typedef TList::Head SomeType;
map[i] = &FunctionsOwner::Function1<SomeType>;
....
}
};
class CFunctionsOwner
{
publuc:
typedef void (CFunctionsOwner::*TMapElement)();
TMapElement m_Map[10];
template <typename T>
void Function1()
{
...
}
};
Но компилятор ругается по поводу CFunctionsOwner::Function1 — declaration syntax error
Отсюда вопрос: возтожно ли вообще передать как паратетр шаблона неконкретизированный шаблон функции (с шаблоном класса все котпилируется )?
Вообще, шаблон может быть параметризован шаблоном.
template< class A, template<class> class B >
class YourTemplateClass
{
typedef B<int> bint_type;
};
class SetOfBTypes
{
template<class T> class BFirst { ... };
template<class T> class BSecond { ... };
// от этих классов требуется, чтобы они были моделью "шаблон с одним параметром - классом"typedef YourTemplateClass< char, BFirst > FirstClass;
};
но не все компиляторы это понимают и любят.
Выход из ситуации — это упрятывание шаблона вглубь.
template< class A, class BWrapper >
{
typedef typename BWrapper::B<int> bint_type;
};
class SetOfBTypes
{
structBFirst
{ template<class T> classB { ... }; };
structBSecond
{ template<class T> classB { ... }; };
// от этих классов требуется, чтобы они были моделью "класс с публичным шаблонным типом B<class>"typedef YourTemplateClass< char, BFirst > FirstClass;
};
Здравствуйте, Кодт, Вы писали:
К>Вообще, шаблон может быть параметризован шаблоном. К>[c] К>template< class A, template<class> class B > К>class YourTemplateClass К>{ К> typedef B<int> bint_type; К>};
Большое спасибо за совет, но, видимо я плохо задал вопрос . Вариант передачи шаблона класса мною рассматривался и принят как резервный. Вопрос в другом: как передать (и объявить) в качестве параметра шаблона шаблон функции?
Задача алгоритма TypeListToFunctionMap заполнить map объектами, которые являются конкретизацией какого-то шаблона. Если объкт есть функция, то и шаблон должен быть шаблоном функции. И, если язык позволякт, то зачем эту функцию зяаварачивать в класс.
Но, видно, не судьба. Сегодня друг прислал книжку C++ Templates: The Complete Guide By David Vandevoorde, Nicolai M. Josuttis. Вот, что умные дядьки пишут :
8.3.4 Template Template Arguments
A template template argument must be a class template with parameters that exactly match the parameters of the template template parameter it substitutes.
Так что, всем спасибо. Пошел писать классы-обвертки
_Macintosh_ wrote:
> Большое спасибо за совет, но, видимо я плохо задал вопрос . Вариант передачи шаблона класса мною рассматривался и принят как резервный. Вопрос в другом: как передать (и объявить) в качестве параметра шаблона шаблон функции?
Никак
> Задача алгоритма TypeListToFunctionMap заполнить map объектами, которые являются конкретизацией какого-то шаблона. Если объкт есть функция, то и шаблон должен быть шаблоном функции. И, если язык позволякт, то зачем эту функцию зяаварачивать в класс.
[]
> Так что, всем спасибо. Пошел писать классы-обвертки
Описал бы не так узко, а big picture, может нашлось бы более интересное решение твоей задачи.
Здравствуйте, _Macintosh_, Вы писали:
_M_>Но, видно, не судьба. Сегодня друг прислал книжку C++ Templates: The Complete Guide By David Vandevoorde, Nicolai M. Josuttis. Вот, что умные дядьки пишут :
Она есть на русском — смотри рецензию на сайте.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, Lorenzo_LAMAS, Вы писали:
L_L>Может я не в кассу — лень разбираться. Но если просто посмотреть на твой код, то я в нем заметил две ошибки, исправь их — может заработает
L_L>
Спасибо, обязательно добавлю. Но это, действительно, не очень существенно, т.к. это работающий код (во всяком случае, на CodeWarrior`е). Мне не нравиться, что TypeListToFunctionMap жестко привязан к имени шаблона FunctionsOwner::template Function1<SomeType>. Хотелось его в параметры шаблона затолкать, но напрямую нельзя... А жаль.
Здравствуйте, MaximE, Вы писали:
ME>Описал бы не так узко, а big picture, может нашлось бы более интересное решение твоей задачи.
Я старался акцентировать внимание на вопросе, который, собственно, теоретический. Хотя, по большому счету, это почти вся задача (мелкомасштабный я какой-то ). По историческим причинам в проекте, в котором я учавствую, принято выставлять наружу из библиотек С-интерфейс. И чтобы не раздувать интерфейс, всякие параметры передаются через Get/SetParameter(long paramID, void* dataStruct, size_t dataStructSize).
Со стороны библиотеки сидит switch по ID, переадресующий вызов куда следует. В общем, классика . Причем, набор параметров меняется в зависимости от режима работы библиотеки. Я хочу это автоматизировать примерно так:
Шаблон для определения внутреннего(библиотечного) типа параметра
template <class SimpleParamType, int ParamID>
struct SParam
{
// внешний(пользовательский) тип параметраtypedef SimpleParamType TUserParamType;
// ID для доступаenum {k_ParamID = ParamID};
TUserParamType m_Param;
TUserParamType GetUserParam() const
{
return m_Param;
}
};
typedef SParam<float, 1> SParam1;
typedef SParam<long, 2> SParam2;
Это конкретный класс, определяющий набор параметров для конкретного режима работы.
class CParamsHolder
{
public:
// текущий набор параметравtypedef TYPELIST_2(SParam1, SParam2) TParamList;
long GetParam(SParam1& param) const
{
...
}
long GetParam(SParam2& param) const
{
...
}
};
Это шаблон диспетчера, конкретизирующийся текущим набором параметров. Шаблон TypelistToFuncMap описан в предыдущем посте.
_Macintosh_ wrote:
> Я старался акцентировать внимание на вопросе, который, собственно, теоретический. Хотя, по большому счету, это почти вся задача (мелкомасштабный я какой-то ). По историческим причинам в проекте, в котором я учавствую, принято выставлять наружу из библиотек С-интерфейс. И чтобы не раздувать интерфейс, всякие параметры передаются через Get/SetParameter(long paramID, void* dataStruct, size_t dataStructSize). > Со стороны библиотеки сидит switch по ID, переадресующий вызов куда следует. В общем, классика . Причем, набор параметров меняется в зависимости от режима работы библиотеки. Я хочу это автоматизировать примерно так:
[]
Если я правильно понял, основная сложность твоей задачи — это преобразование run-time значения в compile time сущность (тип или константу). Конкретно здесь — long в тип.
Здесь эта задача решена посредством генерации массива указателей специализаций фунции по списку типов. Решение хорошее
Здравствуйте, MaximE, Вы писали:
ME>Если я правильно понял, основная сложность твоей задачи — это преобразование run-time значения в compile time сущность (тип или константу). Конкретно здесь — long в тип.
ME>Здесь эта задача решена посредством генерации массива указателей специализаций фунции по списку типов. Решение хорошее
Благодарю за комплемент . Мне кажется, что управлене доступом к свойствам и параметрам — задача очень древняя. Может быть есть какие-то стандартные решения?