0

How can I use an expression or an operator to get the address of a rvalue ?

char buffer[100];
time_t rawtime=time(nullptr); //rawtime used only once ,after that it's abandoned.
strftime(buffer, 80, "%y%m%d %H%M%S", localtime(&rawtime));// rewrite these two lines into one line?

Should act like this:

strftime(buffer, 80, "%y%m%d %H%M%S", localtime(&(time(nullptr))));
iouvxz
  • 89
  • 9
  • 27

1 Answers1

3

The built-in address-of operator requires an lvalue operand, so you need to produce an lvalue somehow.

You can turn rvalues into lvalues with some kind of opposite of std::move, here called stay:

template <typename T>
T & stay(T && x) { return x; }

Usage:

std::localtime(&stay(std::time(nullptr))

Alternatively, you can use some other pre-existing function template that has a reference parameter and provide an explicit const template argument, since rvalues can bind to constant lvalue references. (Usually this is a very dangerous aspect of such interfaces ("rvalue magnets"), but we'll exploit them here for this use case.) One example function template could be std::min, but we can use std::addressof for even greater convenience here:

#include <memory>

// ...
std::localtime(std::addressof<const std::time_t>(std::time(nullptr))
// ...         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • So there is no way I can access the address of a rvalue using just one expression or one operator , It's not supported by C++ standard ,right ? – iouvxz Nov 15 '15 at 01:01
  • @iouvxz: The built-in address-of operator requires an lvalue operand, indeed. You can alternatively use `std::addressof` with an explicit template argument: `std::addressof(std::time(nullptr))`. That's a similar method to the one I presented. I'll update the post. – Kerrek SB Nov 15 '15 at 02:06