Những lý do cho sự tồn tại của là std::decaygì? Trong tình huống nào là std::decayhữu ích?
decay_t<decltype(...)>là một sự kết hợp tốt đẹp, để xem những gì autosẽ suy luận.
Những lý do cho sự tồn tại của là std::decaygì? Trong tình huống nào là std::decayhữu ích?
decay_t<decltype(...)>là một sự kết hợp tốt đẹp, để xem những gì autosẽ suy luận.
Câu trả lời:
<đùa> Rõ ràng nó được sử dụng để phân rã các std::atomicloạ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>::typelà 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ì T1sẽ đượ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_pairtriển khai C ++ 11 thực tế - C ++ 11 make_paircũng mở khóa std::reference_wrappers.
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";
}
decaylà 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.