Nested function và vấn đề khai báo hàm bên trong một hàm khác

Nested function

Nested function là hàm được định nghĩa bên trong một hàm khác.
Nested function được hỗ trợ như là một mở rộng của GNU C, và không được hỗ trợ bởi GNU C++. Mặc dù đã có đề xuất đưa tính năng này lên C++ nhưng nó đã bị từ chối vì nhiều lí do khác nhau ( không có sự hữu dụng nào cho generic programming…. ).
C++ 11 ra đời với tính năng Lambda Expression, như một sự thay thế cho Nested function.
Tuy nhiên chúng ta vẫn có thể khai báo ( declare ) một hàm bên trong một hàm khác ở C++, như là một yếu tố cần cho sự tương thích khi phát triển từ C lên C++

Khai báo hàm bên trong hàm khác ở C++

Việc này giúp tránh được vấn đề làm “pollute global namespace” – có thể hiểu là tránh sự trùng lặp ( về tên ) của một hàm được định nghĩa bên ngoài với một hàm đang có ở global namespace ( hoặc là từ thư viện được include vào chương trình ). Bản chất là dùng tính chất phạm vi của các hàm, biến khi được khai báo, biến/ hàm nào được khai báo gần nhất thì sẽ được ưu tiên sử dụng.

Cá nhân mình không gặp nhiều cách viết khai báo hàm bên trong hàm khác như thế này, cũng có thể là một bad pratice, nhưng vì tò mò muốn biết nên mới tìm hiểu. Thực sự thì mình tin là cũng sẽ không implement cái này nhiều trong code của mình.

Xem xét đoạn code sau:

#include <iostream>
namespace ns
{
void func() {};
}
using namespace std;
int main()
{
void func();
func();
}void func()
{
std::cout << "External function\n";
}

Kết quả sẽ là dòng External function. Việc khai báo hàm func() trong hàm main cho compiler biết rằng kể từ sau việc khai báo, hàm func được sử dụng sẽ là hàm func ở bên ngoài namespace ns.

Cần chú ý ở đây rằng nếu bạn khai báo hàm func ở ngoài ( ngay bên trên) hàm main, trình biên dịch sẽ báo lỗi vì nó không biết ta sẽ sử dụng hàm func nào ( ambiguous ). Việc khai báo ở trong hay ngoài hàm giống nhau ở chỗ compiler sẽ đều đi tìm phần định nghĩa ( definition ) ở tất cả các file khác trong cùng project ( *.h, *.cpp ), từ khoá “extern” là thừa vì nó là mặc định khi declare hàm

Khi bạn include các thư viện ( stl, các thư viện bên thứ 3… ), để sử dụng hàm của riêng bạn, tránh xung đột với các hàm trong các thư viện đó, các bạn cũng có thể sử dụng kĩ thuật này.

Happy codding 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s