Wie sieht `void_t Arbeit

Sah ich Walter Browns Vortrag auf Cppcon14 über moderne template-Programmierung ( Teil I , Teil II), wo er präsentiert seine void_t SFINAE-Technik.

Beispiel:

Eine einfache variable Vorlage ausgewertet void wenn alle template-Argumente sind gut ausgebildet:

template< class ... > using void_t = void;

ist und die folgende Eigenschaft, die überprüft die Existenz einer member-variable namens Mitglied:

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
{ };

Habe ich versucht zu verstehen, warum und wie das funktioniert. Daher ein kleines Beispiel:

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 existiert
    • decltype( A::member ) wohlgeformt ist
    • void_t<> ist gültig und wird ausgewertet void
  • has_member< A , void > und deshalb wählt es die spezielle Vorlage
  • has_member< T , void > und ausgewertet true_type

2. has_member< B >

  • has_member< B , void_t< decltype( B::member ) > >
    • B::member existiert nicht
    • decltype( B::member ) ist schlecht ausgebildet und schlägt im hintergrund fehl (sfinae)
    • has_member< B , expression-sfinae > also diese Vorlage ist verworfen
  • compiler findet has_member< B , class = void > mit void als Standard-argument
  • has_member< B > ausgewertet false_type

http://ideone.com/HCTlBb

Fragen:

1. Ist mein Verständnis von diesem korrekt?

2. Walter Brown erklärt, dass die default-argument, hat genau die gleiche Art wie das void_t für Sie zu arbeiten. Warum ist das so? (Ich sehe nicht, warum diese Typen müssen übereinstimmen, nicht einfach nur irgendein Standard-Typ macht den job?)

  • Ad 2) stellen Sie die statische assert wurde geschrieben als: has_member<A,int>::value. Dann ist die partielle Spezialisierung, die ausgewertet has_member<A,void> nicht mithalten können. Daher muss es has_member<A,void>::value oder mit syntaktischen Zucker, ein Standard-argument des Typs void.
  • Danke, ich werde es Bearbeiten. Mh, ich sehe nicht die Notwendigkeit, mit has_member< T , class = void > säumigen in void noch. Vorausgesetzt, diese Eigenschaft wird nur verwendet werden, mit 1 template-argument zu jeder Zeit, dann wird das default-argument kann jede Art?
  • Interessante Frage.
  • Beachten Sie, dass In diesem Vorschlag, open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4436.pdf, Walter geändert template <class, class = void> zu template <class, class = void_t<>>. So, jetzt sind wir frei, zu tun, was wir wollen, mit void_t alias-template-Umsetzung 🙂
InformationsquelleAutor nonsensation | 2014-12-29
Schreibe einen Kommentar