LINUX.ORG.RU

[C++] как правильно вызвать макрос с аргументом, содержащим запятые?

 


0

2

Сабж. Например есть макрос

#define A(B,C) func(B){C;}
хочется его вызвать как
A(int x,double y,return x*y) 

PS. Еще вопрос - есть ли вообще возможность как то преобразовать хвост из произвольного. кол-ва аргументов, скажем добавить к каждому аргументу одинаковый префикс?

★★★★★

Произвольного кол-ва аргументов в стиле varargs в макросах использовать нельзя, ЕМНИП.

И, поскольку это C++, о макросах лучше вообще забыть.

schizoid ★★★
()

#define A(B,C) func(B){C;}
хочется его вызвать как A(int x,double y,return x*y)

Можно попробовать так: A((int x,double y),return x*y)

произвольного. кол-ва аргументов

Не. Вроде нельзя. А префикс внутрях добавлять так, например: #define A(B,C) func(B){PREFIX##_##C;}

Bad_ptr ★★★★★
()
Ответ на: комментарий от schizoid

Произвольного кол-ва аргументов в стиле varargs в макросах использовать нельзя, ЕМНИП.

да можно вроде

#define TEST1(...) { printf(__VA_ARGS__); }
#define TEST2(format, args...)  \
 fprintf (stderr, format , ## args)
shty ★★★★★
()

Переменное число аргументов доступно в gcc 4.6 со включенным c++0x. Можно передавать что-нибудь в скобках, тогда это считается как один аргумент. Полезно посмотреть на библиотеку из boost, там целый Тьюринг-полный язык на макросах с циклами, списками и т.д.

На макросы не влияет namespace, поэтому лучше их не использовать на с++.

note173 ★★★★★
()
Ответ на: комментарий от note173

На макросы не влияет namespace, поэтому лучше их не использовать на с++.

у макросов свой «namespace» :)

#define MY_SUPER_MACRO

void foo() 
{
    // use macro somehow
} 

#undef MY_SUPER_MACRO
shty ★★★★★
()

[code=c]
#define COMMA ,
#define A(B,C) func(B){C;}

A(int x COMMA double y,return x*y)
[/code]

anonymous
()
Ответ на: комментарий от note173

почему же - можно, но тогда надо создать и заэкспортить другую функцию, которая уже будет вызывать эту внутри

shty ★★★★★
()
Ответ на: комментарий от note173

Кстати, а можно ли как-нибудь, не применяя с++0х, объявить псевдоним для параметризированного типа?

а какой use case?

shty ★★★★★
()
Ответ на: комментарий от shty

Хочу, чтобы boost::shared_ptr<T> был Ref<T>. Использую define, но это не хорошо, в программе используются неймспейсы по назначению.

note173 ★★★★★
()
Ответ на: комментарий от schizoid

Тут проблема не в создании, а в описании полей и методов. Там должно быть именно имя типа.

Ладно, подожду, пока в андроиде включат новый стандарт, а пока пусть остается на define.

note173 ★★★★★
()
Ответ на: комментарий от note173

Хочу, чтобы boost::shared_ptr<T> был Ref<T>.

как то так

template<class T>
struct Ref
{
    typedef boost::shared_ptr<T> type;
};

Ref<SomeClass>::type someClassRef;

?

shty ★★★★★
()
Ответ на: комментарий от shty

Так не должно работать, а во-вторых так некрасиво. define Ref boost::shared_ptr работает, просто хотелось более правильно.

note173 ★★★★★
()
Ответ на: комментарий от note173

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

shty ★★★★★
()
Ответ на: комментарий от shty

Можно, конечно, написать Ref<Class>::strong (...) и Ref<Class>::weak (...), так будет некоторый смысл. Но зато длинные выражения с приведениями станут еще больше.

note173 ★★★★★
()
Ответ на: комментарий от note173

ожно, конечно, написать Ref<Class>::strong (...) и Ref<Class>::weak (...)

а что, хорошая идея, мне нравится

Но зато длинные выражения с приведениями станут еще больше.

use typedef luke :)

shty ★★★★★
()
Ответ на: комментарий от shty

Не хочу для каждого типа добавлять отдельный тип-ссылку (даже два - еще слабые ссылки).

note173 ★★★★★
()
Ответ на: комментарий от shty

я бы здесь макрос убрал бы и втыкнул бы функтор или лямбду

Я бы тоже;-)

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

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

Кодогенерацию что ли воткнуть на этапе сборки...

AIv ★★★★★
() автор топика

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

mix_mix ★★★★★
()
Ответ на: комментарий от AIv

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

template <typename... BaseClasses> 
class ClassName : public BaseClasses... 
{
public:
 
    ClassName (BaseClasses&&... base_classes) : BaseClasses(base_classes)... {}
};

ы?

shty ★★★★★
()
Ответ на: комментарий от schizoid

виртуального конструктора

Пардон, какой ещё виртуальный конструктор? Вы о чём? Может деструктор имелся в виду?

DELIRIUM ☆☆☆☆☆
()
Ответ на: комментарий от DELIRIUM

Да, конечно, деструктора. Опечатался. Спасибо.

schizoid ★★★
()
Ответ на: комментарий от shty

Боюсь что не ы. SWIG скорей всего не поймет, потом там конструкции вида

template <class T, int N1, int N2, ... int Nn> class array{
     T p[N1][N2]...[Nn];
public:
     T& operator []( const indx<n>& I ){ return p[I[0]][I[1]]...[I[n-1]]; }
};
как то так.

Похоже можно таки можно сделать через препроцессор. Во первых пачку аргументов как один можно передать как

#define ARG( args... ) args
#define MYMACROS( a, b, c ) : ...
MACROS( ARG(q,w,e), 123, ARG(z,x) )
Во вторых я подсмотрел в бустовском препроцессоре идею псевдорекурсии;-)

AIv ★★★★★
() автор топика
Ответ на: комментарий от note173

Полезно посмотреть на библиотеку из boost, там целый Тьюринг-полный язык на макросах с циклами, списками и т.д.

Спасибо за наводку, «знал, но забыл»;-)

AIv ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.