อะไรคือสาเหตุของการมีอยู่ของstd::decay? ในสถานการณ์ใดที่std::decayมีประโยชน์?
decay_t<decltype(...)>เป็นการผสมผสานที่ดีเพื่อดูว่าอะไรautoจะอนุมาน
                อะไรคือสาเหตุของการมีอยู่ของstd::decay? ในสถานการณ์ใดที่std::decayมีประโยชน์?
decay_t<decltype(...)>เป็นการผสมผสานที่ดีเพื่อดูว่าอะไรautoจะอนุมาน
                คำตอบ:
<โจ๊ก> เห็นได้ชัดว่ามันใช้เพื่อสลายstd::atomicประเภทกัมมันตภาพรังสีให้กลายเป็นประเภทที่ไม่มีกัมมันตภาพรังสี </joke>
N2609std::decayเป็นกระดาษที่นำเสนอ กระดาษอธิบาย:
พูดง่ายๆ
decay<T>::typeคือการแปลงชนิดข้อมูลเฉพาะตัวยกเว้นว่า T เป็นประเภทอาร์เรย์หรือการอ้างอิงถึงประเภทฟังก์ชัน ในกรณีเหล่านั้นdecay<T>::typeให้ตัวชี้หรือตัวชี้ไปยังฟังก์ชั่นตามลำดับ
ตัวอย่างแรงจูงใจคือ 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); 
}
ซึ่งยอมรับพารามิเตอร์ด้วยค่าเพื่อให้ตัวอักษรสตริงทำงาน:
std::pair<std::string, int> p = make_pair("foo", 0);
ถ้ามันยอมรับพารามิเตอร์โดยอ้างอิงแล้วT1จะถูกหักเป็นประเภทอาร์เรย์และจากนั้นการสร้างpair<T1, T2>จะเป็นรูปแบบที่ไม่ดี
แต่เห็นได้ชัดว่าสิ่งนี้นำไปสู่การไร้ประสิทธิภาพที่สำคัญ ดังนั้นความจำเป็นในdecayการใช้ชุดการแปลงที่เกิดขึ้นเมื่อค่า pass-by-value เกิดขึ้นช่วยให้คุณได้รับประสิทธิภาพของการอ้างอิงพารามิเตอร์ แต่ยังได้รับการแปลงชนิดที่จำเป็นสำหรับรหัสของคุณเพื่อทำงานกับตัวอักษรสตริง ประเภทอาร์เรย์ประเภทฟังก์ชั่นและสิ่งที่ชอบ:
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)); 
}
หมายเหตุ:นี่ไม่ใช่การนำ C ++ 11 make_pairไปใช้จริง - C ++ 11 make_pairยังไม่std::reference_wrapperได้แยกออก
เมื่อจัดการกับฟังก์ชั่นเทมเพลตที่รับพารามิเตอร์ของประเภทเทมเพลตคุณมักจะมีพารามิเตอร์สากล พารามิเตอร์สากลนั้นมักจะมีการอ้างอิงถึงการเรียงลำดับอย่างใดอย่างหนึ่ง พวกมันยังมีคุณสมบัติในการระเหยง่าย ดังนั้นคุณลักษณะส่วนใหญ่จะไม่ทำงานตามที่คุณคาดหวัง:
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-crooked.com/a/24476e60bd906bed
ทางออกที่นี่คือการใช้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มีความก้าวร้าวมากเช่นถ้านำไปใช้กับการอ้างอิงถึงอาร์เรย์จะให้ตัวชี้ โดยทั่วไปแล้วจะมีความก้าวร้าวเกินกว่าที่ IMHO ประเภทนี้จะใช้ในการเปรียบเทียบ
                    remove_const_t< remove_reference_t<T> >จะห่อด้วยเมตาฟังก์ชั่นที่กำหนดเอง