Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Most vexing parse confusion

I'm studying C++11 and I stumbled upon uniform initializers.

I don't understand the following code which should show the "most vexing parse" ambiguity:

#include<iostream>
 
class Timer
{
public:
    Timer() {}
};

int main() 
{
    auto dv = Timer(); // What is Timer() ? And what type is dv?
    int time_keeper(Timer()); // This is a function right? And why isn't the argument " Timer (*) ()" ?
    return 0;
}
like image 461
Marco A. Avatar asked Jun 12 '13 08:06

Marco A.


1 Answers

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.

like image 191
Andy Prowl Avatar answered Oct 17 '22 06:10

Andy Prowl