具有可变参数列表的 c++11 lambda 函数
c++11 lambda function with variable parameter list
我没有在SO中找到这个问题。如果重复请参考答案并关闭此问题。
C++11 lambda 函数可以有可变参数列表吗?
auto displayMessage = [objectLog] (const char * sFormat, ...) {
...
}
是的,语法允许,没有什么禁止的。
A lambda-declarator 在 5.1.2 [expr.prim.lambda] 中定义为:
lambda-declarator:
( parameter-declaration-clause ) mutableopt exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt
并且参数声明子句在8.3.5 [dcl.fct]中定义为:
parameter-declaration-clause:
parameter-declaration-listopt ...opt
parameter-declaration-list , ...
另外,G++、Clang、EDG都可以接受,没有问题。
在幕后,C++11 lambda 生成带有 operator()
成员函数的闭包类型,并且函数没有理由不能有 ...
,例如这个 lambda 表达式:
auto l = [](int, ...) { }
生成这样的类型:
struct unnamed_closure_type {
void operator()(int, ...) const { }
};
这是完全有效的 C++。
我刚刚尝试使用 Apple LLVM 6
(LLVM 3.5svn
),它编译得很好。
我想这里与常规函数调用没有什么不同,唯一被禁止的是使用 auto
关键字。
这比我想象的要容易,就像之前没有任何禁止的那样。
我必须承认我以前可以尝试过,但我是 C++ 初学者,因此我认为它更复杂。这是带有可变参数列表的 lambda 函数的代码。此 lambda 函数用于内部日志记录 - 直接到标准输出或文件。
auto displayMessage = [objectLog] (const char * sFormatString, ...)
{
char sMessage [MAX_LOG_LINE_LENGTH];
va_list vArgPtr;
va_start(vArgPtr, sFormatString);
vsnprintf(sMessage, sizeof(sMessage), sFormatString, vArgPtr);
// EDIT: according to Jonathan Wakely's comment - added va_end()...
va_end(vArgPtr);
if ( objectLog )
{
objectLog->insertLogEntry("%s", sMessage);
}
else
{
printf("%s", sMessage);
}
};
我没有在SO中找到这个问题。如果重复请参考答案并关闭此问题。
C++11 lambda 函数可以有可变参数列表吗?
auto displayMessage = [objectLog] (const char * sFormat, ...) {
...
}
是的,语法允许,没有什么禁止的。
A lambda-declarator 在 5.1.2 [expr.prim.lambda] 中定义为:
lambda-declarator:
( parameter-declaration-clause ) mutableopt exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt
并且参数声明子句在8.3.5 [dcl.fct]中定义为:
parameter-declaration-clause:
parameter-declaration-listopt ...opt
parameter-declaration-list , ...
另外,G++、Clang、EDG都可以接受,没有问题。
在幕后,C++11 lambda 生成带有 operator()
成员函数的闭包类型,并且函数没有理由不能有 ...
,例如这个 lambda 表达式:
auto l = [](int, ...) { }
生成这样的类型:
struct unnamed_closure_type {
void operator()(int, ...) const { }
};
这是完全有效的 C++。
我刚刚尝试使用 Apple LLVM 6
(LLVM 3.5svn
),它编译得很好。
我想这里与常规函数调用没有什么不同,唯一被禁止的是使用 auto
关键字。
这比我想象的要容易,就像之前没有任何禁止的那样。
我必须承认我以前可以尝试过,但我是 C++ 初学者,因此我认为它更复杂。这是带有可变参数列表的 lambda 函数的代码。此 lambda 函数用于内部日志记录 - 直接到标准输出或文件。
auto displayMessage = [objectLog] (const char * sFormatString, ...)
{
char sMessage [MAX_LOG_LINE_LENGTH];
va_list vArgPtr;
va_start(vArgPtr, sFormatString);
vsnprintf(sMessage, sizeof(sMessage), sFormatString, vArgPtr);
// EDIT: according to Jonathan Wakely's comment - added va_end()...
va_end(vArgPtr);
if ( objectLog )
{
objectLog->insertLogEntry("%s", sMessage);
}
else
{
printf("%s", sMessage);
}
};