2

I did not find this question in SO. If it is a duplicate please refer to the answer and close this question.

Can a C++11 lambda function have a variable parameter list?

auto displayMessage = [objectLog] (const char * sFormat, ...) {
     ...
}
2
  • Refer to this: stackoverflow.com/questions/7627098/… Commented Mar 18, 2015 at 13:43
  • @Overflowh, that doesn't seem to say anything about using ... in a C++11 lambda Commented Mar 18, 2015 at 13:53

3 Answers 3

3

Yes, the grammar allows it, and nothing forbids it.

A lambda-declarator is defined in 5.1.2 [expr.prim.lambda] as:

lambda-declarator:
    ( parameter-declaration-clause ) mutableopt exception-specificationopt attribute-specifier-seqopt trailing-return-typeopt

And a parameter-declaration-clause is defined in 8.3.5 [dcl.fct] as:

parameter-declaration-clause:
    parameter-declaration-listopt ...opt
    parameter-declaration-list , ...

Also, G++, Clang and EDG all accept it without problems.

Under the hood, a C++11 lambda generates closure type with an operator() member function, and there is no reason that function can't have ..., e.g. this lambda expression:

auto l = [](int, ...) { }

generates a type like this:

struct unnamed_closure_type {
  void operator()(int, ...) const { }
};

which is perfectly valid C++.

Sign up to request clarification or add additional context in comments.

1 Comment

In fact, Clang won't allow you to use va_start in such lambda, it's a known bug (llvm.org/bugs/show_bug.cgi?id=19617)
1

It was easier than I thought and as meant before nothing forbids it.

I must admit I could have tried it before but I am a C++ beginner and therefore I thought it is more complicated. Here is a code for a lambda function with variable parameter list. This lambda function is used for internal logging - either directly to stdout or to a file.

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);
    }
};

1 Comment

You're missing va_end(vArgPtr)
0

I just tried with Apple LLVM 6 (LLVM 3.5svn) and it compiled just fine. I guess there's nothing very different from regular function calls here, with the only forbidden thing being the use of the auto keyword.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.