0%

C++'s most vexing parse

“C++’s most vexing parse”

When we try to pass a temporary object to construct an other object, it might lead to some unexpected result.

1
2
3
4
5
6
7
class Task {
public:
void operator() () {
//
}
};
std::thread my_thread(Tast()); // We want create a new thread. But ...

As the code presents, we want to create a new thread and pass an temporary object to construct it. However, it will not do it., std::thread my_thread(Tast()); will be parsed as a function declaration.

WHY!!!

1
2
3
4
5
6
7
void f1();
void f2(int val);
void f3(int(val));
void f4(int());
void f5(int);

void f6((int())) // !error

f1 ~ f5 are legal declaration in C++. Even though parameters in f4, f5 will not be used in function’s defination.
To avoid C++ parse std::thread my_thread(Tast()); as a declaration of a function, we can insert parentheses like f6.

1
2
3
4
5
6
7
8
9
10
11
12
// correct way
class Task {
public:
void operator() () {
//
}
};
int main() {
std::thread my_thread((Tast())); // declare an object rather than a function
my_thread.join();
return 0;
}

Defining function in function ?

It seems we can define function in function since C++ might parse thread my_thread(Tast()) as a declaration of a function.

The answer is NO!!!

C++ does not allow nested function. If you do need one, you can use lambda expression in C++11.

1
2
3
4
5
6
7
8
9
10
void f() {
void f2() {} // error!

// lambda expression. Great!
auto lam = [](int val) {
cout << val << endl;
}

lam(1);
}

If we can not define functions in a funtion, Why C++ allowed us declare funtions in funtion, which might lead to ambiguous parsing?

Well, we can delare funtion to notify compiler that thoes funtions were defined in other place.

Like this,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// a.cc
int main() {
extern void f(int val);
f(1);
return 0;
}

// b.cc
#include <iostream>
void f(int val) {
std::cout << val << std::endl;
}

-># g++ a.cc b.cc -o test
-># ./test