Hàm implicit_cast là gì? khi nào tôi nên thích implicit_cast hơn là static_cast?Sự khác nhau giữa static_cast và Implicit_cast là gì?
Trả lời
Tôi đang sao chép từ nhận xét tôi đã thực hiện sang answer this comment ở địa điểm khác.
Bạn có thể truyền xuống với
static_cast
. Không phải như vậy vớiimplicit_cast
.static_cast
về cơ bản cho phép bạn thực hiện bất kỳ chuyển đổi ngầm định nào và ngoài việc đảo ngược bất kỳ chuyển đổi ngầm định nào (tối đa một số giới hạn. Bạn không thể downcast nếu có một lớp cơ sở ảo liên quan). Nhưngimplicit_cast
sẽ chỉ chỉ chấp nhận chuyển đổi ngầm định. không xuống-cast, khôngvoid*->T*
, khôngU->T
nếu T chỉ có nhà xây dựng rõ ràng cho U.
Lưu ý rằng điều quan trọng cần lưu ý sự khác biệt giữa một dàn diễn viên và chuyển đổi. Trong trường hợp không có dàn diễn viên nào diễn ra sau đây
int a = 3.4;
Nhưng chuyển đổi ngầm xảy ra từ đôi đến int. Những thứ như "diễn viên tiềm ẩn" không tồn tại, bởi vì diễn viên luôn là yêu cầu chuyển đổi rõ ràng. Cấu trúc tên cho boost::implicit_cast
là sự kết hợp đáng yêu của "truyền sử dụng chuyển đổi tiềm ẩn". Bây giờ toàn bộ thi hành boost::implicit_cast
là này (giải thích here):
template<typename T> struct identity { typedef T type; };
template<typename Dst> Dst implicit_cast(typename identity<Dst>::type t)
{ return t; }
Ý tưởng là sử dụng một bối cảnh phi suy luận cho tham số t
. Điều đó sẽ tránh những cạm bẫy như sau:
call_const_version(implicit_cast(this)); // oops, wrong!
gì được mong muốn là để viết nó ra như thế này
call_const_version(implicit_cast<MyClass const*>(this)); // right!
Trình biên dịch không thể suy ra những gì gõ mẫu tham số Dst
nên đặt tên, vì nó đầu tiên phải biết những gì identity<Dst>
là, vì nó là một phần của tham số được sử dụng để khấu trừ. Nhưng đến lượt nó phụ thuộc vào tham số Dst
(identity
có thể được sử dụng một cách rõ ràng cho một số loại). Bây giờ, chúng ta có một phụ thuộc vòng tròn, mà Chuẩn chỉ nói một tham số như vậy là một ngữ cảnh không được suy luận, và một đối số mẫu rõ ràng phải được cung cấp.
implicit_cast chuyển đổi loại này sang loại khác và có thể được mở rộng bằng cách viết hàm đúc ngầm, để truyền từ loại này sang loại khác.
ví dụ:
int i = 100;
long l = i;
và
int i = 100;
long l = implicit_cast<long>(i);
là chính xác cùng mã
tuy nhiên bạn có thể cung cấp phôi tiềm ẩn của riêng bạn với nhiều loại riêng của bạn, do quá tải implicit_cast như sau
template <typename T>
inline T implicit_cast (typename mpl::identity<T>::type x)
{
return x;
}
Xem tại đây boost/implicit_cast.hpp để biết thêm
Hope this helps
EDIT
Trang này cũng nói về implicit_cast New C++
Ngoài ra, chức năng chính của static_cast là để thực hiện một thay đổi không, chuyển đổi ngữ nghĩa từ loại này sang loại khác. Loại thay đổi nhưng các giá trị vẫn giống hệt nhau, ví dụ:
void *voidPtr = . . .
int* intPtr = static_cast<int*>(voidPtr);
Tôi muốn xem con trỏ trống này, như thể nó là con trỏ int, con trỏ không thay đổi và nằm trong void voidtrtr có giá trị giống như intPtr. An implicit_cast, loại thay đổi nhưng các giá trị sau khi chuyển đổi cũng có thể khác nhau.
"_chức năng chính của static_cast là thực hiện chuyển đổi không thay đổi hoặc ngữ nghĩa từ kiểu này sang kiểu khác. Kiểu thay đổi nhưng giá trị vẫn giống nhau_" trong trường hợp này ('static_cast
Chuyển đổi ngầm định, chuyển đổi rõ ràng và static_cast là tất cả những thứ khác nhau. tuy nhiên, nếu bạn có thể chuyển đổi hoàn toàn, bạn có thể chuyển đổi một cách rõ ràng và nếu bạn có thể chuyển đổi một cách rõ ràng, bạn có thể truyền tĩnh. Tuy nhiên, điều ngược lại cũng không đúng. Có một mối quan hệ hoàn toàn hợp lý giữa các phôi tiềm ẩn và các phôi tĩnh. Cái cũ là một tập con của cái sau.
Xem phần 5.2.9.3 của ++ Chuẩn C để biết chi tiết
Nếu không, một biểu hiện e có thể chuyển đổi một cách rõ ràng để một kiểu T sử dụng một static_cast dạng static_- cast (e) nếu tờ khai T t (e); được hình thành tốt, đối với một số biến tạm thời là t (8.5).
C++ khuyến khích sử dụng static_casts vì nó làm cho chuyển đổi 'hiển thị' trong chương trình. Cách sử dụng của phôi chính nó chỉ ra một số quy tắc thực thi lập trình có giá trị để sử dụng tốt hơn static_cast.
Thích implcit_cast nếu nó đủ trong trường hợp của bạn.Hàm implicit_cast kém mạnh và an toàn hơn static_cast.
Ví dụ, downcasting từ một con trỏ cơ sở đến một con trỏ có nguồn gốc là có thể với static_cast nhưng không phải với implicit_cast. Cách khác xung quanh là có thể với cả hai phôi. Sau đó, khi truyền từ một cơ sở đến một lớp dẫn xuất, hãy sử dụng implicit_cast, vì nó giữ cho bạn an toàn nếu bạn lẫn lộn cả hai lớp.
Cũng nên nhớ rằng implicit_cast thường không cần thiết. Sử dụng không có cast ở tất cả các công trình hầu hết thời gian khi implicit_cast làm, đó là nơi 'ngầm' đến từ. implicit_cast chỉ cần thiết trong các trường hợp đặc biệt, trong đó loại biểu thức phải được kiểm soát chính xác, để tránh tình trạng quá tải, ví dụ.
Bạn có" bắt nguồn "và" cơ sở "ngược ở đây. Một con trỏ có nguồn gốc luôn có thể được chuyển đổi thành cơ sở (công khai hoặc có thể truy cập), nhưng chuyển đổi xuống đòi hỏi một diễn viên rõ ràng. –
@ AdamH.Peterson Bạn nói đúng. Tôi vừa chỉnh sửa câu trả lời. –
Trong trường hợp bạn đang yêu cầu tăng abt :: implicit_cast; vui lòng chỉnh sửa bài đăng để nói rõ hơn. – Abhay
@Abhay Khái niệm 'implicit_cast' lớn hơn rất nhiều so với Boost - vài năm trước. – curiousguy
@curiousguy: Những thứ như "dàn diễn viên tiềm ẩn" không tồn tại, do diễn viên luôn là yêu cầu chuyển đổi rõ ràng. Đọc câu trả lời được chấp nhận để biết chi tiết ... – Abhay