Walter Brown'un Cppcon14'te SFINAE tekniğini sunduğu modern şablon programlama ( Bölüm I , Bölüm II ) hakkındaki konuşmasını void_t
izledim.
Örnek: Tüm şablon argümanlarının iyi biçimlendirilmiş olup
olmadığını değerlendiren basit bir değişken şablonu verildiğinde void
:
template< class ... > using void_t = void;
ve aşağıdaki özellik olduğunu üyesi değişkeni denilen varlığını denetler üyesi :
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
{ };
Bunun neden ve nasıl çalıştığını anlamaya çalıştım. Bu nedenle küçük bir örnek:
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
vardecltype( A::member )
iyi biçimlendirilmişvoid_t<>
geçerlidir vevoid
has_member< A , void >
ve bu nedenle özel şablonu seçerhas_member< T , void >
ve değerlendirirtrue_type
2. has_member< B >
has_member< B , void_t< decltype( B::member ) > >
B::member
mevcut değildecltype( B::member )
kötü biçimlendirilmiş ve sessizce başarısız (sfinae)has_member< B , expression-sfinae >
yani bu şablon atılır
- derleyici
has_member< B , class = void >
varsayılan argüman olarak void ile bulur has_member< B >
için değerlendirirfalse_type
Sorular:
1. Bu anlayışım doğru mu?
2. Walter Brown, varsayılan argümanın çalışması için kullanılanla aynı tipte olması gerektiğini belirtir void_t
. Neden? (Bu türlerin neden eşleşmesi gerektiğini anlamıyorum, iş sadece varsayılan bir tür değil mi?)
has_member< T , class = void >
temerrüde düşme ihtiyacım void
yok. Bu özelliğin herhangi bir anda yalnızca 1 şablon bağımsız değişkeni ile kullanılacağını varsayarsak, varsayılan bağımsız değişken herhangi bir tür olabilir mi?
template <class, class = void>
etmek template <class, class = void_t<>>
. Şimdi void_t
takma ad şablon uygulamasıyla istediğimizi yapmakta
has_member<A,int>::value
. Ardından, değerlendirilen kısmi uzmanlıkhas_member<A,void>
eşleşemez. Bu nedenle,has_member<A,void>::value
sözdizimsel şekerle varsayılan bir tür argümanı olması gerekirvoid
.