具有可变参数列表的 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);
    }
};