【问题标题】:Need to fix my Variadic Macros需要修复我的可变参数宏
【发布时间】:2015-05-31 06:57:25
【问题描述】:

我想使用可变参数宏,但出现错误

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

【问题讨论】:

  • 您在使用第一个示例时在哪里声明了signIn
  • 是sv的函数。它在 sv 类的头文件中声明。

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


【解决方案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++11c++98 模式下为我编译的完整代码

编辑 2

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

确实,启动我的窗口并在 Visual Studio 中玩耍时,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__)

并且在 Visual Studio 中编译!耶!

【讨论】:

  • 嗯...没有## 代码可以为我正确编译。但是,对于##,即使使用SERVER_RE_2,代码也无法编译。试过g++clang++
  • 我使用 MSVC120。我的代码错误pastebin.com/5T6124Pu。 (但如果使用 RE_1 RE_2 RE_3 而不是 RE,它会编译)
  • @Ufx 这是一个视觉 C++ 错误!但是有一个解决方法 - 请参阅我的新编辑
  • rabensky 非常感谢!现在它的工作。 VS 用红线在这个宏下划线,但这不是一个大问题。此代码是否适用于 gcc 和 clang?
  • @Ufx 是的 :) 刚刚测试确定。
猜你喜欢
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
  • 2011-08-18
  • 2013-05-21
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多