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.