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, ...) {
...
}
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, ...) {
...
}
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++.
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);
}
};
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.