How to decide constexpr to return a reference or not
how to return an lvalue in one case and an rvalue in the other case?
I suppose you can try with decltype(auto)
and a couple of parentheses
template<bool getref>
decltype(auto) get_number() // "decltype(auto)" instead of "auto"
{
if constexpr(getref)
{
return (number); // not "number" but "(number)"
}
else
{
return 123123; // just a random number as example
}
}
std::ref
seems to do the trick for me:
#include <functional>
#include <iostream>
static int number = 15;
template<bool getref>
auto get_number()
{
if constexpr(getref)
{
return std::ref(number); // we want to return a reference here
}
else
{
return 123123; // just a random number as example
}
}
int main(int argc, char **argv)
{
int& ref = get_number<true>();
int noref = get_number<false>();
std::cout << "Before ref " << ref << " and number " << number << std::endl;
ref = argc;
std::cout << "After ref " << ref << " and number " << number << std::endl;
std::cout << "Before noref " << noref << " and number " << number << std::endl;
noref = argc * 2;
std::cout << "After noref " << noref << " and number " << number << std::endl;
}
Try it online!
As expected, changing ref
changes number
(and not noref
), while changing noref
changes nothing else.
Since the behavior is constexpr
and templated, returning std::ref
of number
forces it to actually make a reference.