ผมเฝ้าดูการพูดคุยวอลเตอร์บราวน์ที่ Cppcon14 เกี่ยวกับการเขียนโปรแกรมแม่แบบที่ทันสมัย ( Part I , Part II ) ที่เขานำเสนอของเขาvoid_tเทคนิค SFINAE
ตัวอย่าง: 
กำหนดเทมเพลตตัวแปรแบบง่ายที่ประเมินvoidว่าถ้าอาร์กิวเมนต์เท็มเพลตทั้งหมดมีรูปแบบที่ดี:
template< class ... > using void_t = void;และลักษณะต่อไปนี้ที่ตรวจสอบการมีอยู่ของตัวแปรสมาชิกที่เรียกว่าสมาชิก :
template< class , class = void >
struct has_member : std::false_type
{ };
// specialized as has_member< T , void > or discarded (sfinae)
template< class T >
struct has_member< T , void_t< decltype( T::member ) > > : std::true_type
{ };ฉันพยายามเข้าใจว่าเพราะอะไรและทำงานอย่างไร ดังนั้นตัวอย่างเล็ก ๆ :
class A {
public:
    int member;
};
class B {
};
static_assert( has_member< A >::value , "A" );
static_assert( has_member< B >::value , "B" );1 has_member< A >
- has_member< A , void_t< decltype( A::member ) > >- A::memberที่มีอยู่
- decltype( A::member )มีรูปแบบที่ดี
- void_t<>ถูกต้องและประเมินผลถึง- void
 
- has_member< A , void >และดังนั้นจึงเลือกเทมเพลตพิเศษ
- has_member< T , void >และประเมินผลให้- true_type
2 has_member< B >
- has_member< B , void_t< decltype( B::member ) > >- B::memberไม่ได้อยู่
- decltype( B::member )มีรูปแบบไม่ดีและล้มเหลวอย่างเงียบ ๆ (sfinae)
- has_member< B , expression-sfinae >เทมเพลตนี้จึงถูกยกเลิก
 
- คอมไพเลอร์พบhas_member< B , class = void >กับโมฆะเป็นอาร์กิวเมนต์เริ่มต้น
- has_member< B >ประเมินให้- false_type
คำถาม: 
1. ความเข้าใจของฉันเกี่ยวกับสิ่งนี้ถูกต้องหรือไม่? 
2. วอลเตอร์บราวน์ระบุว่าอาร์กิวเมนต์เริ่มต้นจะต้องเป็นชนิดเดียวกันกับที่ใช้ในvoid_tการทำงาน ทำไมถึงเป็นอย่างนั้น? (ฉันไม่เห็นว่าทำไมประเภทนี้ต้องตรงกันไม่ใช่แค่งานประเภทเริ่มต้นเท่านั้น)  
has_member< T , class = void >ผิดนัดในvoidเลย สมมติว่าคุณสมบัตินี้จะใช้กับอาร์กิวเมนต์ 1 เทมเพลตเมื่อใดก็ได้ดังนั้นอาร์กิวเมนต์เริ่มต้นอาจเป็นประเภทใดก็ได้
                template <class, class = void> template <class, class = void_t<>>ดังนั้นตอนนี้เรามีอิสระที่จะทำสิ่งที่เราต้องการด้วยvoid_tการดำเนินนามแฝงแม่แบบ :)
                
has_member<A,int>::valueลองนึกภาพยืนยันคงเขียนเป็น: จากนั้นความเชี่ยวชาญเฉพาะบางส่วนที่ประเมินว่าhas_member<A,void>ไม่สามารถจับคู่ได้ ดังนั้นจะต้องมีหรือมีน้ำตาลประโยคอาร์กิวเมนต์เริ่มต้นของประเภทhas_member<A,void>::valuevoid