需要修复我的Variadic宏

时间:2015-05-31 06:57:25

标签: c++ c++11 macros variadic-macros

我想使用可变参数宏,但我得到错误

#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);

1 个答案:

答案 0 :(得分:2)

删除额外的##,替换行

    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++11c++98中为我编译的完整代码

修改2

第一个警告warning C4003让我觉得这里存在可变参数宏的基本问题。

确实,启动我的窗户并在visual studio中玩游戏,视觉工作室中存在一个可变宏扩展的错误。

您可以使用以下代码自行查看:

#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__)

并在视觉工作室编译! YAY!