I was wondering if I could use snprintf
formatting in an ostream
such that I could embed the call to snprintf
in the stream expression itself. This compiles in GCC 4.9, but is it OK?
cout << [](char (&&buf) [12], int d) { snprintf(buf, 12, "%d", d); return buf; } ({ }, 15) << endl;
This is well-formed and well-defined. {}
is used to copy-list-initialize an rvalue reference to char [12]
, which creates a temporary char [12]
array to which the reference is bound. This temporary lives until the end of the full expression - in this case, until the semicolon, so a pointer to an element in the array can be safely returned and used for printing within that expression. (The lambda returns a char *
pointing to the first element of this array.)
Standardese:
§8.5 [dcl.init]/p17:
The semantics of initializers are as follows. [...]
- If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).
§8.5.4 [dcl.init.list]/p3:
List-initialization of an object or reference of type
T
is defined as follows:
- [...]
- Otherwise, if
T
is a reference type, a prvalue temporary of the type referenced byT
is copy-list-initialized or direct-list-initialized, depending on the kind of initialization for the reference, and the reference is bound to that temporary. [ Note: As usual, the binding will fail and the program is ill-formed if the reference type is an lvalue reference to a non-const type. —end note ]
§12.2 [class.temporary]/p5:
A temporary bound to a reference parameter in a function call (5.2.2) persists until the completion of the full-expression containing the call.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With