Worth mentioning on top of the reference collapsing rules is how to force d to be an rvalue reference. You can use std::move for this:
int a =4;
auto &&d = std::move(a); // d is type &&
Of course when talking integers, rvalue references are silly, as pass by value is just as efficient. This is useful in forcing move semantic optimizations, say if you wanted to insert a complex type at the end of a function, where that type would go out of scope...
vector<std::string> v;
void f()
{
string s;
foo(s); // do some kind of operation on s.
v.push_back(std::move(s)); // use push_back( &&) instead of push_back(const &);
}