Нужно исправить мои макросы Variadic

Я хочу использовать вариативные макросы, но получаю ошибки

#define SERVER_RE_1(ServerFunction, Type1)                          \
    {                                                               \
        Type1 arg1;                                                 \
        getData(args, arg1);                                        \
        sv. ## ServerFunction ## (ssl, arg1);                       \
    }

#define SERVER_RE_2(ServerFunction, Type1, Type2)                   \
    {                                                               \
        Type1 arg1;                                                 \
        Type2 arg2;                                                 \
        getData(args, arg1, arg2);                                  \
        sv. ## ServerFunction ## (ssl, arg1, arg2);                 \
    }

#define SERVER_RE_3(ServerFunction, Type1, Type2, Type3)            \
    {                                                               \
        Type1 arg1;                                                 \
        Type2 arg2;                                                 \
        Type3 arg3;                                                 \
        getData(args, arg1, arg2, arg3);                            \
        sv. ## ServerFunction ## (ssl, arg1, arg2, arg3);           \
    }

#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define SERVER_RE(...) GET_MACRO(__VA_ARGS__, SERVER_RE_3, SERVER_RE_2, SERVER_RE_1)(__VA_ARGS__)

-

SERVER_RE(signIn, std::string, std::string);

ошибка C2065: 'signIn': необъявленный идентификатор
ошибка C2275: 'std::string': незаконное использование этого типа в качестве выражения

-

Но SERVER_RE_2 работает хорошо.

SERVER_RE2(signIn, std::string, std::string);

person Ufx    schedule 31.05.2015    source источник
comment
Где вы объявили signIn при использовании первого образца?   -  person πάντα ῥεῖ    schedule 31.05.2015
comment
Это функция св. Он объявлен в заголовке класса sv.   -  person Ufx    schedule 31.05.2015


Ответы (1)


Удалите лишние ##, как при замене строк

    sv. ## ServerFunction ## (ssl, arg1, arg2, arg3);           \

с участием

    sv. ServerFunction (ssl, arg1, arg2, arg3);           \

ИЗМЕНИТЬ

Можете попробовать скомпилировать следующий код?

#include <string>
#define SERVER_RE_1(ServerFunction, Type1)                          \
    {                                                               \
        Type1 arg1;                                                 \
        getData(args, arg1);                                        \
        sv. ServerFunction (ssl, arg1);                       \
    }

#define SERVER_RE_2(ServerFunction, Type1, Type2)                   \
    {                                                               \
        Type1 arg1;                                                 \
        Type2 arg2;                                                 \
        getData(args, arg1, arg2);                                  \
        sv.ServerFunction(ssl, arg1, arg2);                 \
    }

#define SERVER_RE_3(ServerFunction, Type1, Type2, Type3)            \
    {                                                               \
        Type1 arg1;                                                 \
        Type2 arg2;                                                 \
        Type3 arg3;                                                 \
        getData(args, arg1, arg2, arg3);                            \
        sv.ServerFunction(ssl, arg1, arg2, arg3);           \
    }

#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define SERVER_RE(...) GET_MACRO(__VA_ARGS__, SERVER_RE_3, SERVER_RE_2, SERVER_RE_1)(__VA_ARGS__)

struct C{
  template<class T1>
  void signIn(int,T1){}
  template<class T1, class T2>
  void signIn(int,T1,T2){}
  template<class T1, class T2,class T3>
  void signIn(int,T1,T2,T3){}
};

template<class T1>
void getData(int,T1){}
template<class T1, class T2>
void getData(int,T1,T2){}
template<class T1, class T2, class T3>
void getData(int,T1,T2,T3){}

int main(){
  C sv;
  int args=0,ssl=0;
  SERVER_RE(signIn, std::string);
  SERVER_RE(signIn, std::string, std::string);
  SERVER_RE(signIn, std::string, std::string, std::string);
}

Это полный код, который компилируется как есть для меня в режимах g++ и clang++, в режимах c++11 и c++98.

Изменить 2

Это первое предупреждение warning C4003 заставляет меня думать, что здесь есть основная проблема с вариативными макросами.

Действительно, загружая мои окна и играя в визуальной студии, в визуальной студии есть ошибка в расширении вариативного макроса.

Вы можете убедиться в этом сами, используя следующий код:

#include <stdio.h>
#define AAA(a,b) printf("%d %d\n",a,b)
#define BBB(...) AAA(__VA_ARGS__)
int main(){
  AAA(1,2); // works
  BBB(3,4); // warning + error
}

Но не беспокойтесь! Вы можете это исправить! Используйте мой приведенный выше код, но замените строку

#define SERVER_RE(...) GET_MACRO(__VA_ARGS__, SERVER_RE_3, SERVER_RE_2, SERVER_RE_1)(__VA_ARGS__)

с участием

#define GET_MACRO_X(X) GET_MACRO X
#define SERVER_RE(...) GET_MACRO_X((__VA_ARGS__, SERVER_RE_3, SERVER_RE_2, SERVER_RE_1))(__VA_ARGS__)

и это компилируется в Visual Studio! УРА!

person rabensky    schedule 31.05.2015
comment
Хм... без ## у меня код компилируется правильно. Однако с ## код не компилируется даже с SERVER_RE_2. Пробовал на g++ и clang++. - person rabensky; 31.05.2015
comment
Я использую MSVC120. Мои ошибки для вашего кода pastebin.com/5T6124Pu. (Но он компилируется, если использовать RE_1 RE_2 RE_3 вместо RE) - person Ufx; 01.06.2015
comment
@Ufx Это визуальная ошибка C++! Но есть обходной путь - см. мою новую правку - person rabensky; 01.06.2015
comment
Рабенский Спасибо большое! Теперь это работа. VS подчеркивает красной линией этот макрос, но это не большая проблема. Этот код работает на gcc и clang? - person Ufx; 01.06.2015
comment
@Ufx да :) Только что проверил, чтобы убедиться. - person rabensky; 01.06.2015