Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ajax/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 便携式可变宏_C++_Visual Studio_Gcc_C Preprocessor_Variadic Macros - Fatal编程技术网

C++ 便携式可变宏

C++ 便携式可变宏,c++,visual-studio,gcc,c-preprocessor,variadic-macros,C++,Visual Studio,Gcc,C Preprocessor,Variadic Macros,我想制作一个变量宏,它只需为每个参数调用某个函数(比如,最多6个)。到目前为止,我一直在MSVC中使用以下代码: #define do_write2(x,y) do{do_write(x);do_write(y);}while(0) #define do_write3(x,y,z) do{do_write(x);do_write(y);do_write(z);}while(0) #define do_write4(x,y,z,w) do{do_write(x);do_write(y);do_wr

我想制作一个变量宏,它只需为每个参数调用某个函数(比如,最多6个)。到目前为止,我一直在MSVC中使用以下代码:

#define do_write2(x,y) do{do_write(x);do_write(y);}while(0)
#define do_write3(x,y,z) do{do_write(x);do_write(y);do_write(z);}while(0)
#define do_write4(x,y,z,w) do{do_write(x);do_write(y);do_write(z);do_write(w);}while(0)
#define do_write5(x,y,z,w,t) do{do_write(x);do_write(y);do_write(z);do_write(w);do_write(t);}while(0)
#define do_write6(x,y,z,w,t,u) do{do_write(x);do_write(y);do_write(z);do_write(w);do_write(t);do_write(u);}while(0)
#define expand(x) x
#define _get_write(_1,_2,_3,_4,_5,_6,name,...) name
#define dumpval(...) expand(_get_write(__VA_ARGS__,do_write6,do_write5,do_write4,do_write3,do_write2,do_write))expand((__VA_ARGS__))
由于MSVC中对
\uu VA\u ARGS\uuu
的特殊处理,需要使用
展开
,否则我会

error C2660: 'do_write' : function does not take 6 arguments
但是,现在我需要在GCC中构建相同的代码,它有问题:

error: ‘do_write3’ was not declared in this scope

只需删除
expand
包装就可以了。但是,在这两种情况下,是否有任何“正确”的方法可以使代码在不使用
#ifdef
的情况下编译?

对于变量参数宏,有各种技术,在这里讨论:

下面是一些您可能感兴趣的实现。我个人认为,
call\u vla2
是最好的选择,前提是您有C++11支持。如果这是不可能的,告诉我们更多关于您的问题

#include <iostream>

// target function
void z(int i) {
    std::cout << "[" << i << "]\n";
}

// 1. manually specifying the argument count
#define call1(a)        do{z(a);}while(0)
#define call2(a,b)      do{z(a);z(b);}while(0)
#define call3(a,b,c)    do{z(a);z(b);z(c);}while(0)
#define call_n(n, ...)  call ## n (__VA_ARGS__)

// 2. using a variable-length array (GCC compatible)
// thanks to https://stackoverflow.com/a/824769/6096046
#define call_vla(...) do { \
        int args[] = { __VA_ARGS__ }; \
        for(size_t i = 0; i < sizeof(args)/sizeof(*args); i ++) \
            z(args[i]); \
    } while(0)

// 3. using a variable-length array and C++11
#define call_vla2(...) for(auto x : { __VA_ARGS__ }) z(x);

// 4. using C++11 variadic templates
template <typename... T>
void call_n_times() {}

template <typename... T>
void call_n_times(int a, T... other) {
    z(a), call_n_times(other...);
}

#define call_template(...) call_n_times(__VA_ARGS__)

// tests
int main() {
    call_n(1, 88);      call_n(3, 1,2,3);
    call_vla(88);       call_vla(1,2,3);
    call_vla2(88);      call_vla2(1,2,3);
    call_template(88);  call_template(1,2,3);
    return 0;
}
#包括
//目标函数
虚空z(内部i){

std::这是否必须使用宏来完成?你能使用
C++11
吗?我想我可以重写它来使用可变模板,因为代码很旧,所以我从未考虑过这种可能性。