Макрос + шаблон = не компилится
От: 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: Макрос + шаблон = не компилится
От: SchweinDeBurg Россия http://zarezky.spb.ru/
Дата: 08.10.04 13:32
Оценка:
Здравствуйте, SergH, Вы писали:

А если так:

typedef Some<int, char> Some_IC;
TYPEDEF_AS_BASE(Some_IC)
- Искренне ваш, Поросенок Пафнутий ~ ICQ#116846877
In Windows, there’s always a catch… © Paul DiLascia
Re: Макрос + шаблон = не компилится
От: Sergey J. A. Беларусь  
Дата: 08.10.04 13:35
Оценка: 57 (5)
Здравствуйте, 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: Макрос + шаблон = не компилится
От: Andrew S Россия http://alchemy-lab.com
Дата: 08.10.04 14:56
Оценка: 15 (1)
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 работает нормально.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: Макрос + шаблон = не компилится
От: SergH Россия  
Дата: 08.10.04 15:01
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Я сделал в свое время вот так:


..

Спасибо, твой вариант мне больше понравился.
Делай что должно, и будь что будет
Re[3]: Макрос + шаблон = не компилится
От: Andrew S Россия http://alchemy-lab.com
Дата: 08.10.04 15:13
Оценка:
AS>>Я сделал в свое время вот так:

SH>..


SH>Спасибо, твой вариант мне больше понравился.


А мне наоборот, вариант с COMMA Там возможностей больше. Хотя визуально, конечно, мой вариант посимпатичнее.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[4]: Макрос + шаблон = не компилится
От: SergH Россия  
Дата: 08.10.04 15:16
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>А мне наоборот, вариант с COMMA Там возможностей больше. Хотя визуально, конечно, мой вариант посимпатичнее.


А зачем много возможностей? Пока мне не понадобится аналогичным образом обработать десять запятых, я буду предпочитать более симпатичный ..
Делай что должно, и будь что будет
Re: Макрос + шаблон = не компилится
От: yxiie Украина www.enkord.com
Дата: 08.10.04 17:59
Оценка: 6 (1)
Здравствуйте, 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 >>
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.