2017-03-08 134 views
-1

实现一个断言宏我偶然发现了Xcode叮当中的一个问题。C++ variadic宏到可变参数函数

我使用下面的代码:

void Log(LogLevel logLevel, const std::string& message); 

std::string FormatString(const char* format, ...); 

#define LOG(Level, Format, ...)          \ 
{                 \ 
    std::string _ac_err_str_ = FormatString(Format, ##__VA_ARGS__); \ 
    Log(Level, _ac_err_str_);          \ 
} 

#define checkf(expr, Format, ...) { if(!(expr)) { LOG(LL_ErrorMessage, TXT("Log in file ") __FILE__ TXT(" at line %d: ") TXT(#expr) TXT(". ") Format, __LINE__, __VA_ARGS__); } } 

一切正常用MSVC但锵我得到以下错误:Expected expression

我已经找到了问题在这条线:

std::string _ac_err_str_ = FormatString(Format, ##__VA_ARGS__); 

更具体地说,问题在##__VA_ARGS__部分,因为如果我删除它的一切编译。

另外,如果我传递第三个参数,将其编译宏,如:

checkf(false, "Error message");  // Won't compile 
checkf(false, "Error %s", "message"); // Will compile 

好像有一个错误在经过宏的可变参数,以FormatString,但我不能找出原因或如何解决这个问题。

+1

'## __ VA_ARGS__'不是标准配置。不要期望它能够轻松地工作。它看起来并没有什么特别的理由来使用一个宏来替代'LOG'的可变参数模板。 – chris

+1

请自己帮忙,了解可变参数模板 –

+0

我了解可变参数模板。无论如何,发现如何解决这个问题,因为我已经在代码中的很多点上使用了这个宏,并且不想改变它们。 – zeb

回答

0

显然在Clang的,我需要改变我的checkf宏一样,我用##__VA_ARGS__,而不是仅仅__VA_ARGS__

#define checkf(expr, Format, ...) { if(!(expr)) { LOG(LL_ErrorMessage, TXT("Log in file ") __FILE__ TXT(" at line %d: ") TXT(#expr) TXT(". ") Format, __LINE__, ##__VA_ARGS__); } } 

通知。

它与MSVC和Clang一起编译。