Макрос + шаблон = не компилится
От:
SergH
Дата: 08.10.04 13:25
Оценка:
Все здравствуйте.
Вот такой код:
#define TYPEDEF_AS_BASE( t ) typedef t Base;
template <class T1, class T2>
class Some
{
};
TYPEDEF_AS_BASE(Some< int , char >)
void main()
{
}
Не компилится. Сначала идёт объясняющее всё предупреждение:
warning C4002: too many actual parameters for macro 'TYPEDEF_AS_BASE'
А потом ещё несколько ошибок.
Очевидно, препроцессор неправильно истолковвывает запятую в
TYPEDEF_AS_BASE(Some< int , char >)
Проблема в том, что как-то иначе он её толковать не может — компилятор ещё даже не запустился. Скобки помогают успокоить перпроцессор, но, так как выражение
typedef (Some<int , char >) Base;
Отвергается компилятором, не спасают ситуацию в целом.
Подскажите, как с этим бороться. Запускаю на VC 6 и 2003
Делай что должно, и будь что будет
Re: Макрос + шаблон = не компилится
От:
Glоbus
Дата: 08.10.04 13:31
Оценка:
Здравствуйте, SergH, Вы писали:
SH>Все здравствуйте.
SH>Вот такой код:
SH>SH>#define TYPEDEF_AS_BASE( t ) typedef t Base;
SH>template <class T1, class T2>
SH>class Some
SH>{
SH>};
SH>TYPEDEF_AS_BASE(Some< int , char >)
SH>void main()
SH>{
SH>}
SH>
SH>Не компилится. Сначала идёт объясняющее всё предупреждение:
а так не поможет?
#define TYPEDEF_AS_BASE( t1, t2, t3 ) typedef t1<t2,t3> Base;
template <class T1, class T2>
class Some
{
};
TYPEDEF_AS_BASE( Some, int , char )
void main()
{
}
Удачи тебе, браток!
Re: Макрос + шаблон = не компилится
Здравствуйте, SergH, Вы писали:
А если так:
typedef Some<int , char > Some_IC;
TYPEDEF_AS_BASE(Some_IC)
- Искренне ваш,
Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Макрос + шаблон = не компилится
Здравствуйте, SergH, Вы писали:
SH>Отвергается компилятором, не спасают ситуацию в целом.
SH>Подскажите, как с этим бороться. Запускаю на VC 6 и 2003
первое, что приходит в голову:
#define TYPEDEF_AS_BASE( t ) typedef t Base;
#define COMMA ,
TYPEDEF_AS_BASE(std::pair< int COMMA int >)
У меня работает.
Re[2]: Макрос + шаблон = не компилится
От:
SergH
Дата: 08.10.04 13:37
Оценка:
Здравствуйте, Glоbus, Вы писали:
G>а так не поможет?
...
Сорри, не до конца описал задачу. Макрос это DECLARE_CLASSFACTORY_EX из ATL, а я неосторожно написал фабрику класса с двумя параметрами шаблона.. Поэтому подгонять макрос под меня нельзя. Можно, конечно, от него отказатьсь и развернуть вручную, но хотелось бы как-то иначе.
Делай что должно, и будь что будет
Re[3]: Макрос + шаблон = не компилится
От:
Кодт
Дата: 08.10.04 13:39
Оценка:
Здравствуйте, SergH, Вы писали:
SH>Сорри, не до конца описал задачу. Макрос это DECLARE_CLASSFACTORY_EX из ATL, а я неосторожно написал фабрику класса с двумя параметрами шаблона.. Поэтому подгонять макрос под меня нельзя. Можно, конечно, от него отказатьсь и развернуть вручную, но хотелось бы как-то иначе.
Сделай
typedef YourCoolFactoryTemplate<X,Y> TheCoolFactory;
DECLARE_CLASSFACTORY_EX( TheCoolFactory );
Перекуём баги на фичи!
Re[2]: Макрос + шаблон = не компилится
От:
SergH
Дата: 08.10.04 13:40
Оценка:
Здравствуйте, SchweinDeBurg, Вы писали:
SDB>А если так:
SDB>SDB>typedef Some<int , char > Some_IC;
SDB>TYPEDEF_AS_BASE(Some_IC)
SDB>
В лоб так не получится, т.к. ситуация примерно такая:
#define TYPEDEF_AS_BASE_MY(obj) TYPEDEF_AS_BASE(Some<obj, char >)
А вводить своим макросом дополнительный typedef не хочется.
Делай что должно, и будь что будет
Re[2]: Макрос + шаблон = не компилится
От:
SergH
Дата: 08.10.04 13:40
Оценка:
Здравствуйте, Sergey J. A., Вы писали:
SJA>первое, что приходит в голову:
SJA>#define TYPEDEF_AS_BASE( t ) typedef t Base;
SJA>#define COMMA ,
SJA>TYPEDEF_AS_BASE(std::pair< int COMMA int >)
SJA>У меня работает.
Супер!
Делай что должно, и будь что будет
Re: Макрос + шаблон = не компилится
SH>Отвергается компилятором, не спасают ситуацию в целом.
SH>Подскажите, как с этим бороться. Запускаю на VC 6 и 2003
Я сделал в свое время вот так:
// 2 arguments template to macro param overcome
#define MAKE_MACRO_PARAM(x, y) x, y
Ну и, соотв., использовать как:
MY_COOL_MACRO(param1, MAKE_MACRO_PARAM(Some< int , char >))
На всей линейке VC работает нормально.
Re[2]: Макрос + шаблон = не компилится
От:
SergH
Дата: 08.10.04 15:01
Оценка:
Здравствуйте, Andrew S, Вы писали:
AS>Я сделал в свое время вот так:
..
Спасибо, твой вариант мне больше понравился.
Делай что должно, и будь что будет
Re[3]: Макрос + шаблон = не компилится
AS>>Я сделал в свое время вот так:
SH>..
SH>Спасибо, твой вариант мне больше понравился.
А мне наоборот, вариант с COMMA
Там возможностей больше. Хотя визуально, конечно, мой вариант посимпатичнее.
Re[4]: Макрос + шаблон = не компилится
От:
SergH
Дата: 08.10.04 15:16
Оценка:
Здравствуйте, Andrew S, Вы писали:
AS>А мне наоборот, вариант с COMMA Там возможностей больше. Хотя визуально, конечно, мой вариант посимпатичнее.
А зачем много возможностей? Пока мне не понадобится аналогичным образом обработать десять запятых, я буду предпочитать более симпатичный
..
Делай что должно, и будь что будет
Re: Макрос + шаблон = не компилится
Здравствуйте, SergH, Вы писали:
SH>Все здравствуйте.
SH>Вот такой код:
SH>SH>#define TYPEDEF_AS_BASE( t ) typedef t Base;
SH>template <class T1, class T2>
SH>class Some
SH>{
SH>};
SH>TYPEDEF_AS_BASE(Some< int , char >)
SH>void main()
SH>{
SH>}
SH>
я когда-то постоянно тыкался в такие проблемы препроцессора, пробовал решать склеивающими макросами, но вcе это не то!
в конце концов решил проблему так, что ничего лишнего дописывать не нужно.
если заюзать один мой workaround
/*
* unwind_params.h - macro parameters handling
* Copyright (c) 2004 by Yaroslav Yanovsky
*/
#ifndef BFX_UTILITY_UTILITY_UNWIND_PARAMS_H
#define BFX_UTILITY_UTILITY_UNWIND_PARAMS_H
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/cat.hpp>
#include <boost/preprocessor/facilities/apply.hpp>
#include <boost/preprocessor/facilities/identity.hpp>
#include <boost/preprocessor/logical/not.hpp>
#include <boost/preprocessor/facilities/empty.hpp>
// magic workaround
#define BOOST_PP_EXPR_IIF_BOOST_PP_CHECK_RESULT_
#pragma warning(disable: 4003)
// #pragma warning(once: 4003)
/**
@ingroup UtilityHelper
Unwinds parameters as raw comma-separated list. Useful for handling
templates
*/
#define BFX_UNWIND_PARAMS(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
P1\
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P2),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P2),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P2))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P3),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P3),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P3))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P4),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P4),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P4))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P5),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P5),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P5))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P6),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P6),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P6))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P7),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P7),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P7))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P8),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P8),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P8))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P9),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P9),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P9))() \
BOOST_PP_COMMA_IF(BOOST_PP_NOT(BOOST_PP_CAT(BOOST_PP_APPLY(#P10),0))) \
BOOST_PP_IF(BOOST_PP_CAT(BOOST_PP_APPLY(#P10),0), BOOST_PP_EMPTY, BOOST_PP_IDENTITY(P10))()
#endif // BFX_UTILITY_UTILITY_UNWIND_PARAMS_H
то твой код можно переписать так:
#include "unwind_params.h"
#define TYPEDEF_AS_BASE(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) \
typedef BFX_UNWIND_PARAMS(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10) Base;
template <class T1, class T2>
class Some
{
};
TYPEDEF_AS_BASE(Some< int , char >) // <-- использование не изменилось
void main()
{
}
то можно юзать именно в таком виде как ты хотел, с любым количеством вложенных шаблонных параметров
TYPEDEF_AS_BASE(Some<int , char >)
TYPEDEF_AS_BASE(Some<int >)
TYPEDEF_AS_BASE(Some<int , char , Object, pair<long , int > >)
TYPEDEF_AS_BASE(Some<int , Some< Some<int , int > > >)
вот так-то boost::preprocessor и рулит
... << RSDN@Home 1.1.3 stable >>
Пока на собственное сообщение не было ответов, его можно удалить.
Удалить