C++'s most vexing parse again
In a function declaration, arguments of type array decay into pointers to the first element, arguments of type function decay into a function pointer, so the signature would be:
widget w( gadget(*)(), doodad(*)() );
That is, a function that takes as the first argument a pointer to a function taking no arguments and returning gadget
, that takes as second argument a pointer to a function taking no arguments and returning a doodad
and that the function itself returns a widget
There are even more interesting or confusing cases, like:
// assume 'x' is a variable defined somewhere:
widget w(gadget(x));
How could that be interpreted as a function declaration? I mean, x
is a variable, right? Well, when declaring a variable you can add extra parenthesis, so gadget x;
and gadget (x);
both declare the same variable x
. The same applies to function arguments so the code above looks like a declaration of a function that takes a first argument named x
of type gadget
and returns a widget
...
Most vexing parse C++11
what exactly this line does
It creates a temporary X
, value-initialising it by calling the default constructor, and then uses that to initialise a Y
variable, calling the const X&
conversion constructor.
where is connection to Most vexing parse
If you were to try to write this using old-school initialisation syntax
Y y (X());
then the so-called "most vexing parse" would interpret this as a function, rather than a variable, declaration: a function called y
, with return type Y
and a single parameter, whose type is a (pointer to a) function returning X
.
You could add extra parentheses, so that it can't be interpreted as a function declaration:
Y y ((X()));
or, since C++11, you can use brace-initialisation as your example does.
How can I avoid most vexing parse with direct value initialization?
Use copy initialisation and rely on C++17's guarantee that copy elision will happen.
For example:
struct Foo
{
Foo() = default;
Foo(Foo const&) = delete;
};
int main()
{
auto f = Foo();
}
https://godbolt.org/g/9tbkjZ
What is the purpose of the Most Vexing Parse?
Let's say MVP didn't exist.
How would you declare a function?
A foo();
would be a variable definition, not a method declaration. Would you introduce a new keyword? Would you have a more awkward syntax for a function declaration? Or would you rather have
A foo;
define a variable and
A foo();
declare a function?
Your slightly more complicated example is just for consistency with this basic one. It's easier to say "everything that can be interpreted as a declaration, will be interpreted as a declaration" rather than "everything that can be interpreted as a declaration, will be interpreted as a declaration, unless it's a single variable definition, in which case it's a variable definition".
This probably isn't the motivation behind it though, but a reason it's a good thing.
A confusing detail about the Most Vexing Parse
istream_iterator<int>(cin)
is exactly the same as istream_iterator<int> cin
but with superfluous parens. This declarator syntax was inherited from C, and I think even the inventor of C (Ken Thompson?) described it as a mistake.
Most vexing parse: why doesn't `g( ( f() ) );` call `f`'s default constructor and pass the result to `g`'s ctor that takes a `f`?
The first one declares a function called f
that takes no parameters and returns g
.
g( f() );
// ^ ^ redundant set of parentheses
The second one is the same, with yet another redundant set of parentheses (remember that you can have as many declarations of the same functions as you wish). They are not always useless, though. You need them, say, to declare a function that returns a function pointer:
// function taking an int and returning
// a pointer to a function that takes a char
// and returns a g
g ( *f(int) )(char);
//^ ^ needed, syntax error without them
As for third:
When #1 and #2 are there, you've got a function declaration for f
in main
and g myG( ( f() ) );
is parsed as a declaration of an object of type g
, named myG
and initialized with a result of a function call. You get a linker error because there's no definition for f
.
When #1 and #2 are commented out, the type f
is visible, and the disambiguation with parentheses kicks in:
g myG( ( f() ) )
// ^ ^ these force an expression
Without that pair, you'd get another function declaration.
What you want is this:
( g(f()) );
// ^ ^ must be an expression as declarations can't be parenthesized
or something less Lisp-y: static_cast<g>(f());
How do I determine if a given date is the Nth weekday of the month?
You could change the check of the week so the function would read:
private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){
int d = date.Day;
return date.DayOfWeek == dow && (d-1)/7 == (n-1);
}
Other than that, it looks pretty good and efficient.
Related Topics
Visual Studio Code, #Include ≪Stdio.H≫ Saying "Add Include Path to Settings"
What Are the Gcc Default Include Directories
Why Do C++11-Deleted Functions Participate in Overload Resolution
How Does C++ Linking Work in Practice
Does Const Mean Thread-Safe in C++11
Tellg() Function Give Wrong Size of File
Return Statement VS Exit() in Main()
What's a Proper Way of Type-Punning a Float to an Int and Vice-Versa
Capturing Stdout from a System() Command Optimally
How to Include Libraries in Visual Studio 2012
Using Opencv and Svm With Images
Writing Your Own Stl Container
What Is the Windows Equivalent For En_Us.Utf-8 Locale
Do Rvalue References to Const Have Any Use
Incrementing in C++ - When to Use X++ or ++X
How to Use Break to Exit Multiple Nested 'For' Loops