Những lý do cho sự tồn tại của là std::decay
gì? Trong tình huống nào là std::decay
hữu ích?
decay_t<decltype(...)>
là một sự kết hợp tốt đẹp, để xem những gì auto
sẽ suy luận.
Những lý do cho sự tồn tại của là std::decay
gì? Trong tình huống nào là std::decay
hữu ích?
decay_t<decltype(...)>
là một sự kết hợp tốt đẹp, để xem những gì auto
sẽ suy luận.
Câu trả lời:
<đùa> Rõ ràng nó được sử dụng để phân rã các std::atomic
loại phóng xạ thành các loại không phóng xạ. </ đùa>
N2609 là giấy đề xuất std::decay
. Bài viết giải thích:
Nói một cách đơn giản,
decay<T>::type
là phép biến đổi kiểu nhận dạng trừ khi T là kiểu mảng hoặc tham chiếu đến kiểu hàm. Trong những trường hợp đódecay<T>::type
, tương ứng mang lại một con trỏ hoặc một con trỏ tới một hàm.
Ví dụ tạo động lực là C ++ 03 std::make_pair
:
template <class T1, class T2>
inline pair<T1,T2> make_pair(T1 x, T2 y)
{
return pair<T1,T2>(x, y);
}
đã chấp nhận các tham số của nó theo giá trị để làm cho chuỗi ký tự hoạt động:
std::pair<std::string, int> p = make_pair("foo", 0);
Nếu nó chấp nhận tham số của nó bằng tham chiếu, thì T1
sẽ được suy ra dưới dạng kiểu mảng, và sau đó xây dựng mộtpair<T1, T2>
sẽ không được định dạng.
Nhưng rõ ràng điều này dẫn đến sự thiếu hiệu quả đáng kể. Do đó, cần phải decay
áp dụng tập hợp các phép biến đổi xảy ra khi giá trị truyền qua xảy ra, cho phép bạn có được hiệu quả của việc lấy tham số theo tham chiếu, nhưng vẫn có được các phép biến đổi loại cần thiết để mã của bạn hoạt động với chuỗi ký tự, kiểu mảng, kiểu hàm và tương tự:
template <class T1, class T2>
inline pair< typename decay<T1>::type, typename decay<T2>::type >
make_pair(T1&& x, T2&& y)
{
return pair< typename decay<T1>::type,
typename decay<T2>::type >(std::forward<T1>(x),
std::forward<T2>(y));
}
Lưu ý: đây không phải là make_pair
triển khai C ++ 11 thực tế - C ++ 11 make_pair
cũng mở khóa std::reference_wrapper
s.
Khi xử lý các hàm mẫu lấy tham số của loại mẫu, bạn thường có các tham số phổ quát. Các tham số phổ quát hầu như luôn luôn là các tham chiếu của loại này hay loại khác. Họ cũng có thể dễ bay hơi đủ điều kiện. Như vậy, hầu hết các đặc điểm loại không hoạt động trên chúng như bạn mong đợi:
template<class T>
void func(T&& param) {
if (std::is_same<T,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
int main() {
int three = 3;
func(three); //prints "param is not an int"!!!!
}
http://coliru.stacked-crooking.com/a/24476e60bd906bed
Giải pháp ở đây là sử dụng std::decay
:
template<class T>
void func(T&& param) {
if (std::is_same<typename std::decay<T>::type,int>::value)
std::cout << "param is an int\n";
else
std::cout << "param is not an int\n";
}
decay
là rất tích cực, ví dụ nếu được áp dụng cho một tham chiếu đến mảng, nó mang lại một con trỏ. Nó thường quá tích cực đối với loại IMHO siêu lập trình này.
remove_const_t< remove_reference_t<T> >
, có thể được gói trong một siêu dữ liệu tùy chỉnh.