C++ std:any Ví dụ

C Std Any Vi Du



Trong lập trình C++, “std::any” từ Thư viện mẫu chuẩn (STL) giới thiệu kiểu gõ động để xử lý dữ liệu không đồng nhất. Không giống như các vùng chứa truyền thống, “std::any” cho phép lưu trữ các giá trị của bất kỳ loại nào trong một vùng chứa duy nhất, nâng cao tính linh hoạt trong các tình huống mà các loại dữ liệu không xác định hoặc thay đổi trong thời gian chạy. Cách tiếp cận bất khả tri về kiểu này thúc đẩy một chương trình chung cho phép các nhà phát triển tạo ra một mã dễ thích ứng và biểu cảm hơn trong khi vẫn duy trì sự an toàn của kiểu. Trong phần khám phá này, chúng ta sẽ đi sâu vào các tính năng của “std::any”, cách sử dụng và ví dụ thực tế minh họa vai trò của nó trong việc viết mã C++ mạnh mẽ và linh hoạt.

Ví dụ 1: Cách sử dụng cơ bản của Std::Any

Trước tiên, hãy cùng khám phá một ví dụ đơn giản để chứng minh cách sử dụng cơ bản của “std::any”. Hãy xem xét một tình huống trong đó bạn cần một hàm để chấp nhận nhiều loại tham số khác nhau:







Đây là đoạn mã:



#include
#include

quá trình vô hiệuBất kỳ ( const std::any & giá trị ) {
nếu như ( giá trị.has_value ( ) ) {
std::cout << 'Loại giá trị được lưu trữ:' << giá trị.type ( ) .tên ( ) << std::endl;

nếu như ( giá trị.type ( ) == kiểu chữ ( int ) ) {
std::cout << 'Giá trị: ' << std::any_cast < int > ( giá trị ) << std::endl;
} khác nếu như ( giá trị.type ( ) == kiểu chữ ( gấp đôi ) ) {
std::cout << 'Giá trị: ' << std::any_cast < gấp đôi > ( giá trị ) << std::endl;
} khác nếu như ( giá trị.type ( ) == kiểu chữ ( std::chuỗi ) ) {
std::cout << 'Giá trị: ' << std::any_cast < std::chuỗi > ( giá trị ) << std::endl;
} khác {
std::cout << 'Loại không được hỗ trợ!' << std::endl;
}
} khác {
std::cout << 'Không có giá trị nào được lưu trữ trong std::any.' << std::endl;
}
}

int chính ( ) {
quá trìnhBất kỳ ( 42 ) ;
quá trìnhBất kỳ ( 3.14 ) ;
quá trìnhBất kỳ ( std::chuỗi ( 'Xin chào, std::any!' ) ) ;
quá trìnhBất kỳ ( 4,5f ) ; // Không được hỗ trợ kiểu

trở lại 0 ;
}


Trong ví dụ này, chúng tôi xác định hàm “processAny” lấy tham chiếu “std::any” làm tham số và kiểm tra nội dung của nó. Bên trong hàm, trước tiên chúng ta kiểm tra xem biến “std::any” có giá trị được lưu trữ bằng has_value() hay không. Nếu có một giá trị, chúng tôi xác định loại giá trị được lưu trữ bằng cách sử dụng type().name() và tiến hành in giá trị tương ứng dựa trên loại của nó. Sau đó, hàm main thể hiện tiện ích của “processAny” bằng cách gọi nó với các kiểu khác nhau: số nguyên (42), số double (3.14) và một chuỗi (“Xin chào, std::any!”). Hàm xử lý thích hợp từng loại và in các giá trị tương ứng. Tuy nhiên, khi cố gắng xử lý số dấu phẩy động (4.5f), không được hỗ trợ trong ví dụ này, chương trình sẽ xử lý tình huống một cách khéo léo bằng cách chỉ ra rằng loại đó không được hỗ trợ.



Đầu ra được tạo ra là:






Điều này cho thấy cách “std::any” cho phép xử lý động các loại dữ liệu khác nhau, khiến nó trở thành một công cụ linh hoạt để lập trình chung trong C++.

Ví dụ 2: Lưu trữ các loại do người dùng xác định

Ví dụ thứ hai khám phá cách loại động này trong Thư viện mẫu tiêu chuẩn (STL) điều chỉnh liền mạch các cấu trúc dữ liệu tùy chỉnh. Tập trung vào loại do người dùng xác định, cấu trúc điểm, chúng tôi giới thiệu cách “std::any” xử lý các phiên bản của cấu trúc đó.



Đây là mã:

#include
#include

lớp MyClass {
công cộng:
Lớp học của tôi ( giá trị int ) : dữ liệu ( giá trị ) { }

dữ liệu in vô hiệu ( ) hằng số {
std::cout << 'Dữ liệu trong MyClass:' << dữ liệu << std::endl;
}

riêng tư:
dữ liệu int;
} ;

int chính ( ) {
std::any AnyObject = MyClass ( 42 ) ;

nếu như ( AnyObject.has_value ( ) ) {
tự động & myClassInstance = std::any_cast < Lớp học của tôi &> ( bất kỳ đối tượng nào ) ;
myClassInstance.printData ( ) ;
} khác {
std::cout << 'Không có giá trị nào được lưu trữ trong std::any.' << std::endl;
}

trở lại 0 ;
}


Trong đoạn mã C++ này, chúng tôi tạo một ví dụ đơn giản để minh họa việc sử dụng loại “std::any” với lớp do người dùng định nghĩa có tên là “MyClass”. Trong lớp, có một biến thành viên riêng được gọi là “dữ liệu” và một phương thức công khai gọi là printData() để hiển thị giá trị của dữ liệu này. Một giá trị số nguyên được truyền và gán cho thành viên “dữ liệu” trong hàm tạo.

Trong hàm “main”, chúng ta khởi tạo một đối tượng của “MyClass” với giá trị ban đầu là 42 và sau đó lưu trữ nó trong biến “std::any” có tên là “anyObject”. Điều này thể hiện khả năng của “std::any” trong việc chứa các phiên bản của các lớp do người dùng xác định.

Sau đó, chúng ta sử dụng câu lệnh “if” để kiểm tra xem “anyObject” có giá trị hay không bằng phương thức has_value(). Nếu có một giá trị, chúng tôi truy xuất đối tượng được lưu trữ bằng cách sử dụng “std::any_cast”. “std::any_cast” được sử dụng với đối số mẫu “MyClass&” để truyền đối tượng được lưu trữ tới tham chiếu của “MyClass”. Sau đó, tham chiếu này, “myClassInstance”, được sử dụng để gọi phương thức printData(), thể hiện khả năng truy cập và vận hành trên loại được lưu trữ do người dùng xác định trong “std::any”.

Nếu không có giá trị nào được lưu trữ trong “std::any”, chúng tôi sẽ in một thông báo biểu thị điều này. Kiểm tra có điều kiện này đảm bảo rằng chúng tôi xử lý các tình huống trong đó biến “std::any” có thể trống.

Đây là đầu ra:

Ví dụ 3: Container hỗn hợp các loại

Trong lập trình, “thùng chứa kiểu hỗn hợp” dùng để chỉ cấu trúc dữ liệu có khả năng chứa các phần tử của các loại dữ liệu đa dạng, có thể không liên quan. Tính linh hoạt này rất có giá trị khi xử lý các tình huống trong đó các kiểu dữ liệu không xác định được tại thời điểm biên dịch hoặc thay đổi linh hoạt trong quá trình thực hiện chương trình. Trong C++, “std::any” minh họa khái niệm này, cho phép tạo một vùng chứa duy nhất để lưu trữ các giá trị của các loại khác nhau.

Hãy cùng khám phá một tình huống trong đó chúng ta tạo một vùng chứa chứa nhiều loại khác nhau:

#include
#include
#include

int chính ( ) {

std::vectơ < std::bất kỳ > thùng chứa hỗn hợp;

hỗn hợpContainer.push_back ( 42 ) ;
hỗn hợpContainer.push_back ( 3.14 ) ;
hỗn hợpContainer.push_back ( std::chuỗi ( 'Xin chào' ) ) ;
hỗn hợpContainer.push_back ( ĐÚNG VẬY ) ;

( const tự động & phần tử: hỗn hợpContainer ) {
nếu như ( loại nguyên tố ( ) == kiểu chữ ( int ) ) {
std::cout << 'Số nguyên:' << std::any_cast < int > ( yếu tố ) << std::endl;
} khác nếu như ( loại nguyên tố ( ) == kiểu chữ ( gấp đôi ) ) {
std::cout << 'Gấp đôi: ' << std::any_cast < gấp đôi > ( yếu tố ) << std::endl;
} khác nếu như ( loại nguyên tố ( ) == kiểu chữ ( std::chuỗi ) ) {
std::cout << 'Sợi dây: ' << std::any_cast < std::chuỗi > ( yếu tố ) << std::endl;
} khác nếu như ( loại nguyên tố ( ) == kiểu chữ ( bool ) ) {
std::cout << 'Boolean:' << std::any_cast < bool > ( yếu tố ) << std::endl;
} khác {
std::cout << 'Loại không xác định' << std::endl;
}
}

trở lại 0 ;
}


Trong hình minh họa này, chúng tôi trình bày khái niệm về vùng chứa loại hỗn hợp sử dụng C++ và tính năng “std::any”. Chúng tôi tạo “std::vector” có tên là “mixedContainer” để đóng vai trò là nơi chứa các phần tử của các loại dữ liệu khác nhau. Bằng cách sử dụng hàm “push_back”, chúng tôi điền vào vùng chứa này nhiều phần tử khác nhau bao gồm số nguyên (42), số kép (3.14), một chuỗi (“Xin chào”) và Boolean (đúng).

Khi lặp qua “mixedContainer” bằng vòng lặp “for”, chúng tôi sử dụng hàm type() để xác định kiểu dữ liệu của từng phần tử một cách linh hoạt. Bằng cách sử dụng “std::any_cast”, chúng tôi trích xuất và in các giá trị tương ứng dựa trên loại của chúng. Ví dụ: nếu phần tử có kiểu “int”, chúng ta sẽ in nó dưới dạng số nguyên. Nếu nó thuộc loại “double”, chúng ta sẽ in nó dưới dạng double, v.v.

Đây là đầu ra được tạo ra:

Ví dụ 4: Xử lý lỗi với Std::Any

Xử lý lỗi khi sử dụng “std::any” liên quan đến việc kiểm tra xem loại đó có được hỗ trợ hay không hoặc liệu một giá trị có được lưu trữ hay không. Trong ví dụ này, chúng tôi trình bày cách xử lý các loại không được hỗ trợ:

#include
#include

int chính ( ) {
std::any myAny = 42 ;

thử {

giá trị gấp đôi = std::any_cast < gấp đôi > ( myAny ) ;
std::cout << 'Giá trị: ' << giá trị << std::endl;
} nắm lấy ( const std::bad_any_cast & Nó là ) {

std::cerr << 'Lỗi: ' << e.cái gì ( ) << std::endl;
}

trở lại 0 ;
}


Chúng ta bắt đầu bằng cách khởi tạo biến “std::any”, “myAny”, với giá trị 42 của kiểu số nguyên. Bên trong khối “thử” tiếp theo, chúng tôi thực hiện một nỗ lực rõ ràng để chuyển giá trị số nguyên này thành giá trị “double” bằng cách sử dụng thao tác “std::any_cast”. Tuy nhiên, vì loại thực tế được lưu trữ trong “myAny” là số nguyên nên thao tác truyền này không hợp lệ đối với loại “double” dẫn đến loại không khớp.

Để quản lý lỗi tiềm ẩn này một cách khéo léo, chúng tôi triển khai xử lý ngoại lệ bằng khối “bắt” được thiết kế để bắt loại ngoại lệ cụ thể là “std::bad_any_cast”. Trong trường hợp truyền không thành công, khối “catch” sẽ được kích hoạt và chúng tôi tạo thông báo lỗi bằng cách sử dụng “std::cerr” để thông báo bản chất của lỗi. Chiến lược xử lý lỗi này đảm bảo rằng chương trình của chúng tôi có thể xử lý một cách khéo léo các tình huống trong đó kiểu truyền cố gắng xung đột với kiểu thực tế được lưu trữ trong biến “std::any”.

Phần kết luận

Trong bài viết này, chúng ta đã khám phá các ứng dụng của “std::any” trong C++, một vùng chứa kiểu động được giới thiệu trong C++ cho các giá trị thuộc nhiều loại khác nhau. Chúng tôi đã chứng minh tính linh hoạt của nó thông qua nhiều ví dụ khác nhau, giới thiệu các tình huống từ cách sử dụng cơ bản đến xử lý các loại do người dùng xác định và các bộ sưu tập không đồng nhất. Chúng tôi đã chứng minh ứng dụng thực tế của nó trong các tình huống mà loại dữ liệu không được biết tại thời điểm biên dịch. Ngoài ra, chúng tôi đã khám phá về các kỹ thuật xử lý lỗi, nhấn mạnh tầm quan trọng của việc quản lý khéo léo các loại không được hỗ trợ thông qua xử lý ngoại lệ.