c++ - 带括号和不带括号的可变参数之间的区别

标签 c++ variadic-functions parentheses

为什么在第一个代码中使用括号有效,而第二个代码则无效?

在第一个代码中,我仅使用带括号的可变参数,第二个代码有一个带可变参数的整数参数,如果我在调用函数时使用括号,它将不起作用。

#include <bits/stdc++.h>

void func( char* szFormat, ... );

#define M1(a)  M2(a)
#define M2(b) func b

int main()
{
    M1(("Hello %s %d\n", "world",2015)); // this works
    return 0;
}

void func( char* szFormat, ... )
{
    char      trace_str[1000];
    va_list   arg_list;
    std::string str;

    va_start(arg_list, szFormat);
    vsprintf(trace_str, szFormat, arg_list);
    va_end(arg_list);

    str += trace_str;
    std::cout << str << std::endl;
}

下面的代码无法使用括号。

#include <bits/stdc++.h>

void func( int year, char* szFormat, ... );

#define M1(a,...)  M2(a, __VA_ARGS__)
#define M2 func 

int main()
{
 // M1(2015, ("Hello %s", "world")); // this doesn't works
    M1(2015, "Hello %s", "world");   // this way works
    return 0;
}

void func(int year, char* szFormat, ... )
{
    char      trace_str[1000];
    va_list   arg_list;
    std::string str;


    va_start(arg_list, szFormat);
    vsprintf(trace_str, szFormat, arg_list);
    va_end(arg_list);

    str += trace_str;
    std::cout << str << " " << year << std::endl;

}

谢谢大家!

最佳答案

查看预处理输出就足以理解这一点。

输入文件:

void func( int year, char* szFormat, ... );

#define M1(a,...)  M2(a, __VA_ARGS__)
#define M2 func 

int main()
{
    M1(2015, ("Hello %s", "world")); // this doesn't works
    M1(2015, "Hello %s", "world");   // this way works
    return 0;
}

c++ -E foo.cpp 的输出:

# 1 "ess.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 155 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "ess.cpp" 2
void func( int year, char* szFormat, ... );




int main()
{
    func(2015, ("Hello %s", "world"));
    func(2015, "Hello %s", "world");
    return 0;
}

相关部分在这里:

    M1(2015, ("Hello %s", "world")); // this doesn't works
    M1(2015, "Hello %s", "world");   // this way works

    func(2015, "Hello %s", "world");
    func(2015, "Hello %s", "world");

该宏仅由预处理器解释。如果放置两层括号,则函数调用中会多出一层,并且不会给出预期结果。这里编译器只会看到内部 block 中的逗号运算符,会看到一个 void evaluataion 或 "Hello %s" 后跟 "world" 并且将以 结尾>func(2015,“世界”);。但是 func(2015, ("Hello %d", 12)); 将以 func(2015, 10); 结尾,并出现语法错误无已知转换第二个参数从“int”到“char *”


在第一个代码中,您有 #define M2(b) func b 删除了一个括号级别,因此

M1(("Hello %s %d\n", "world",2015));

被(正确地)预处理为

func ("Hello %s %d\n", "world",2015);

关于c++ - 带括号和不带括号的可变参数之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32103575/

相关文章:

c++ - "Generic"C++ 中的迭代器

C++ 如何在模板中推断 Callable 的类型(参数列表和返回值)

Bash 命令组 : Why do curly braces require a semicolon?

c++ - 括号中的变量 C++

不带括号的 Perl 方法调用

c++ - 如何从 OpenCL 访问 OpenCV UMat (gpu) 缓冲区?

c++ - 类构造函数 "C2248: ' std::basic_ios<_Elem,_Traits>::basic_ios':无法访问类 'std::basic_ios<_Elem,_Traits>"中声明的私有(private)成员

c++ - 如何seccomp一个子进程?

c++ - 接受字符串和整数的可变参数函数,格式化后者并连接所有?

Java:重载方法解析和可变参数——令人困惑的例子