Here:
auto dv = Timer();
You have an object of type Timer called dv that is being copy-initialized from a temporary (the expression on the right side of the = sign).
When using auto to declare a variable, the type of that variable is the same as the type of the expression that initializes it - not considering cv-qualifiers and references here.
In your case, the expression that initializes dv has type Timer, and so dv has type Timer.
Here:
int time_keeper(Timer());
You declare a function called time_keeper that returns an int and takes as its input a pointer to a function which returns a Timer and takes no argument.
And why isn't the argument Timer (*) () ?
Functions decay to pointers when passed as an argument, so the type of time_keeper is actually int(Timer(*)()).
To convince yourself, you could try compiling this little program:
#include <type_traits>
struct Timer { };
int main()
{
int time_keeper(Timer());
static_assert(
std::is_same<
decltype(time_keeper),
int(Timer(*)())
>::value,
"This should not fire!");
}
Here is a live example.