Search code examples
c++language-lawyerundefined-behaviorlifetime

Passing a temporary by const pointer instead of const reference; is this workaround well-formed?


Apparently, according to the C++ standard, one can't pass a const pointer to a temporary as an argument to a function, while it's totally fine to pass a const reference instead, even though both things are essentially the same.

This is puzzling, and the only explanation I have so far is that C++ can't be subtle enough to allow taking temporary's address as long as said address doesn't outlive the expression. We can trick it into allowing this, though. My question is, will it still be a well-formed program?

Here's the code:

#include <string>
#include <iostream>

std::string const * constRefToPtr( std::string const & v )
{
  return &v;
}

void takeStringPtr( std::string const * s )
{
  std::cout << *s << std::endl;
}

int main()
{
  // This one isn't allowed by the standard
  // takeStringPtr( &std::string( "Hello, world" ) );

  // However, this is just fine, apparently. Is this a well-formed program though?
  takeStringPtr( constRefToPtr( std::string( "Hello, world" ) ) );

  return 0;
}

As you can see, we're introducing a helper to convert a const reference to a const pointer. As far as I can tell, since the temporary should survive until the end of the expression, this is a well-formed program. Am I right?

If I am, is there such a helper in the standard library already?

P.S. In case you are wondering why I need this in the first place, I have a function which takes a const pointer instead of a const reference because it allows passing nullptr. I'd still like to be able to pass temporaries to it, though.


Solution

  • this is a well-formed program. Am I right?

    It is indeed well formed.

    is there such a helper in the standard library already?

    It would be std::addressof, but the overload for temporary (rvalue) is deleted on purpose (to have similar restriction than &temporary()).