2017-01-24 4 views
14

Mein Verständnis über den Template argument deduction for class templates Vorschlag war, das Verhalten von Template-Funktionen und Template-Klassen in Deduktionskontexten zu homogenisieren. Aber ich denke, dass ich etwas falsch verstanden hätte.C++ 17 Klassenvorlage Teilabzug

Wenn wir diese Vorlage bezweckt:

template <std::size_t S, typename T> 
struct test 
{ 
    static constexpr auto size = S; 
    using type_t = T; 

    test(type_t (&input)[size]) : data(input) {} 
    type_t (&data)[size]{}; 
}; 

Ich neige dazu, eine Hilfsfunktion als syntaktischen Zucker verwenden zur Erstellung test Objekte:

template <std::size_t S, typename T> 
test<S, T> helper(T (&input)[S]) { return input; } 

, die unten wie gezeigt verwendet werden können:

int main() 
{ 
    int buffer[5]; 

    auto a = helper<5, int>(buffer); // No deduction 
    auto b = helper<5>(buffer);  // Type deduced 
    auto c = helper(buffer);   // Type and size deduced 

    std::cout << a.size << b.size << c.size; 

    return 0; 
} 

Die Code über die Ausgänge 555 wie erwartet. Ich habe das gleiche in Wandbox versucht, den neueren Compiler Setup mit:

int main() 
{ 
    int buffer[5]; 

    test<5, int> a(buffer); // No deduction: Ok. 
    test<5> b(buffer);  // Type deduced: FAILS. 
    test c(buffer);   // Type and size deduced: Ok. 

    std::cout << a.size << b.size << c.size; 

    return 0; 
} 

Es ist wie für Klassenvorlagen Vorlage Argument Abzug sieht funktioniert nur alle Parameter herzuleiten, war ich beiden Verhaltensweisen erwartet (Helferfunktion und Klasse Vorlage), um dasselbe zu sein, habe ich etwas falsch verstanden?


Die letzten Compilern availables in Wandbox sind gcc HEAD 7.0.1 201701 und Klirren HEAD 5.0.0 (trunk).

+2

Ist 'type_t (& Daten) [size] {};' ein Referenzfeld? Ist das '{}' ein Initialisierer? Kompiliert das? Auch * sintaktischer Zucker * klingt ziemlich ungezogen. :) – wally

+2

Beachten Sie, dass [das Hinzufügen eines expliziten * Deduktionsleitfadens] (http://melpon.org/wandbox/permlink/VEE5DyIE3w3LEGEX) nicht hilft.Ich glaube, dass Teilabzug nicht unterstützt wird, da der Standard einen Abzug-Platzhalter in Form eines * Vorlagennamens * * definiert (d. H. Ohne '<...>' Syntax) *. Daher ist "test <5>" kein gültiger Deduktions-Platzhalter. –

+0

@Muscampester 'type_t (& data) [Größe] {};' ist eine Array-Referenz, ja. Das '{}' ist in der Tat der Initialisierer, und es kompiliert [probieren Sie es aus!] (Http://melpon.org/wandbox/permlink/KCkDg5EEIKbZbPU3). Über * sintactic sugar * was soll ich sagen ...: '(Englisch ist nicht meine Mutter tonghe und ich mache viele Fehler! –

Antwort

11

Von diesem ausgezeichneten trip report von Botond Ballo:

Das Merkmal, wie ursprünglich vorgeschlagen, eine Bestimmung zur teilweisen Abzug enthalten, in denen Sie explizit einige der Vorlage Argumente angeben, und den Rest abgeleitet werden, aber dies wurde über Bedenken gezogen, dass es in einigen Fällen sehr verwirrend sein kann:

// Would have deduced tuple<int, string, float>, 
// but tuple<int> is a well-formed type in and of itself! 
tuple<int> t(42, "waldo", 2.0f); 
+2

Ich finde diese Argumentation sehr seltsam. Also haben wir zuerst 'std :: make_tuple (42," waldo ", 2.0f):' angeblich die ganze Zeit falsch gemacht und den Leuten beigebracht, dass es falsch ist, Template-Argumente anzugeben, wenn sie abgeleitet werden. Nun, indem wir dies verbieten, machen wir den Abzug für die Klassenvorlage so, dass sie auf andere Weise funktioniert als die Funktion Eins (Inkonsistenz) und eine Tonne gültiger Anwendungsfälle blockiert (anders als bei erfundenen Tupelbeispielen). – Predelnik

12

Hier scheint es einen Widerspruch zu geben. Mit Blick auf P0091R3, so scheint es klar, dass teilweise Angabe von Parametern sollte erlaubt werden:

Wir schlagen vor, ein Template-Name zu einer Klasse-Vorlage als einfacher-Typ-Spezifizierer oder mit teilweise geliefert expliziten Template-Argumenten mit Bezug zu ermöglichen in zwei Kontexte:

Aber die aktuelle Normen Wortlaut im gleichen Vorschlag sieht eine Möglichkeit nicht bieten „teilweise geliefert explizite Template-Argumente“ zu behandeln. template-name als Simple-Type-Specifier darf keine Template-Argumente haben.

Nach der Spezifikation selbst scheint das Verhalten des Compilers korrekt zu sein.

+3

Ja, das Papier ist insbesondere ein ziemlich ungeheuerlicher Fall des Autors versäumt, die einleitenden Teile synchron zu halten, wenn der Wortlaut und das Design überarbeitet werden.Das Ergebnis ist leider ein aktiv irreführender einleitender Abschnitt, –

+0

Gut, dass sie noch ein Treffen haben, bevor sie die Schlussabstimmung haben wollen. –

+1

@MikelF: Sie gehen davon aus, dass sie eine teilweise Spezifikation erlauben werden. Die Inkongruenz in der Schrift deutet darauf hin, dass das der Ausschuss gewählt hat * zu entfernen *, anstatt die ursprünglicher Verfasser, der einfach einen Fehler in seiner Benennung macht –

Verwandte Themen