This code causes compilation error (most vexing parse)
#include <iostream>
class A {
int a;
public:
A(int x) :a(x) {}
};
class B {
public:
B(const A& obj) { std::cout << "B\n";}
void foo() {std::cout << "foo\n";}
};
int main()
{
int test = 20;
B var(A(test)); //most vexing parse
var.foo();
return 0;
}
But if I pass 20
instead of test
(A(20)
instead of A(test)
), there is no compilation error.
#include <iostream>
class A {
int a;
public:
A(int x) :a(x) {}
};
class B {
public:
B(const A& obj) { std::cout << "B\n";}
void foo() {std::cout << "foo\n";}
};
int main()
{
int test = 20;
//B var(A(test));
B var(A(20)); //ok works fine
var.foo();
return 0;
}
Why is this not considered as most vexing parse? What is the difference between these two code versions?
Use this online free Code Diff Tool for comparing two text files. This tool provides an easy way to highlight the differences between the two inputted texts. Using the tool is super easy; input the two texts in separate boxes and you can see the output right below.
Updated: 08/02/2020 by Computer Hope. Software versioning is a way to categorize the unique states of computer software as it is developed and released. The version identifier is usually a word, a number, or both. For example, version 1.0 is commonly used to denote the initial release of a program.
The basic idea to make this comparison would be to use Array. split to get arrays of parts from the input strings and then compare pairs of parts from the two arrays; if the parts are not equal we know which version is smaller.
In software development, versioning allows development teams to keep track of changes they make to the project code. The changes may include new functions, features or bug fixes. Minor changes can also be tracked in a similar manner.
A variable can be defined like
type(name)
Because of that
B var(A(test));
declares a function named var
that returns a B
and takes an A
named test
. In
B var(A(20));
if you tried to do the same thing, the A
parameter would be called 20
, which is not a valid variable name. Since it cannot be the name of a variable we know it is a value and instead we are constructing a variable named var
of type B
with the value of A(20)
.
The most-vexing-parse issue is a problem of grammar, not semantics. Grammatically, A(test)
boils down to identifier : OPEN_PAREN : identifier : CLOSE_PAREN
. In context, this is ambiguous because the second identifier could be a variable name or a typename. The compiler has to pick a way of interpreting this sequence of tokens, and neither one is incorrect.
By contrast, A(20)
boils down to identifier : OPEN_PAREN : integer_literal : CLOSE_PAREN
. An integer literal cannot be interpreted as an identifier, so there is no way to interpret it as a typename. It must therefore be parsed as an expression which initializes an object of type A
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With