2016-11-22 1 views
15

In C++ 17 wir ungefähr wieC++ Vorlage Klasse Abzug (P0091R0) für Funktionsargumente

std::pair p = {1,3}; // compiler deduces template parameters to pair<int,int> 

Aus der Dokumentation zu cppreference tun kann ich verstehen, dass das Folgende nicht:

template<class T1, class T2> 
void bar(std::pair<T1,T2>) 
{} 
void foo() 
{ 
    bar({1,3}); // No deduction of pair template arguments 
} 

Kann das jemand bestätigen und einen Einblick geben, warum das nicht funktioniert? Technisch sollte das funktionieren, oder? Gab es irgendwelche Diskussionen, um diese Arbeit zu machen, oder ist es eine Art Aufsicht?

+0

Denken Sie darüber nach - wir müssen wissen, welcher Konstruktor mit den geschweiften Klammern verwendet wird, aber um zu wissen, welcher zu verwenden ist, müssen wir den Typ kennen, aber wir kennen den Typ nicht, bis wir den Konstruktor finden (die Konstruktoren können sein für jede Typensubstitution unterschiedlich dank expliziter Spezialisierung) – milleniumbug

+0

@milleniumbug Dieses Argument würde genauso für den normalen Deklarationsfall gelten - Spezialisierungen werden nicht berücksichtigt. – Barry

+0

@Barry Außer im Fall der Funktionsvorlage haben Sie mehrere mögliche Ziele und die Liste der Vorlagenparameter kann beliebig kompliziert sein. –

Antwort

11

Die Referenz ist korrekt. Vorlage Argument Abzug für Klassenvorlagen, wie sie derzeit gilt angenommen ausschließlich auf Erklärungen (und explizite Typkonvertierungen - die in Bezug auf Erklärungen definiert sind), in [dcl.type.class.deduct]:

Wenn ein Platzhalter für einen davon abgeleitete Klasse-Typ als im Decl-specifier erscheint Decl-specifier-Seq eine einfachen Deklaration, den init-declarator dieser Erklärung wird

von der Form

declarator-IDattribute-Spezifizierer-seq optInitialisierer

Der Platzhalter durch den Rückgabetyp der Funktion, die durch die Überladungsauflösung für Klassenschablone Abzug (13.3.1.8) ersetzt ist, ausgewählt. Wenn die Init-Deklarator-Liste mehr als einen Init-Deklarator enthält, muss der Typ, der den Platzhalter ersetzt, in jedem Abzug gleich sein. [Beispiel:

template<class T> struct container { 
    container(T t) {} 
    template<class Iter> container(Iter beg, Iter end); 
}; 

template<class Iter> 
container(Iter b, Iter e) -> container<typename std::iterator_traits<Iter>::value_type>; 

std::vector<double> v = { /* ... */}; 
container c(7);       // OK, deduces int for T 
auto d = container(v.begin(), v.end()); // OK, deduces double for T 
container e{5, 6};      // error, int is not an iterator 

-Ende Beispiel]

war nichts in dem Vorschlag oder der angenommene Formulierung über eine Klasse Template-Spezialisierung von einem verspannt-init-Liste herzuleiten.