Корректен ли этот код?
В первом случае у вас объект уничтожается раньше ссылки.
Во втором случае время жизни ссылки и объекта одинаково, так что это рабочий пример.
Нет никаких временных объектов. Есть стек и есть куча. Понимание разницы эти двух областей памяти отвечает на 90% вопросов в C++.
В стандарте есть правило, по которому при создании константной ссылки на автоматически управляемый объект его время жизни расширяется до времени жизни константной ссылки. Однако это не относится к оператору return и есть особое правило для списков инициализации (подробнее  тут). Соответственно, в следующем примере функция getRef некорректна, но функция foo реализована корректно.const std::string &getRef() {
    std::string tmpObject = "123";
    return tmpObject;
}

void foo(){
    const std::string& ref = getRef();
    std::cout << ref; // Выведет 123
}
В любом случае, использование такого подхода не имеет смысла - можно просто полагаться на оптимизацию возвращаемого значения и писать так:std::string getStr() {
    std::string tmpObject = "123";
    return tmpObject;
}

void foo(){
    std::string str = getStr();
    std::cout << str; // Выведет 123
}

// На крайний случай можно так - это точно корректно, но лучше не нужно - иначе кто-нибудь 
// может случайно удалить const, что приведёт к проблемам. 
void bar(){
    const std::string& ref = getStr();
    std::cout << ref; // Выведет 123
}