Kann ich zwischen überladenen Template-Funktionen zu einem eingeschränkteren disambiguieren?

7

Der Code

%Vor%

Der Fehler

%Vor%

Die Frage

Ist es möglich, den Fehler im Code zu lösen?

    
Bartek Banachewicz 28.08.2014, 11:48
quelle

4 Antworten

14

Das Einschränken von Funktionen mit SFINAE führt keine Reihenfolge ein, es bedeutet nur, dass eine eingeschränkte Funktion aufrufbar oder nicht aufrufbar ist. Wenn also die erste Überladung aktiviert ist, haben Sie zwei nicht eindeutige Funktionen.

Die einfachste Lösung besteht darin, die Umkehrung derselben Einschränkung zu verwenden, um die zweite Überladung zu deaktivieren, so dass nur eine für einen gegebenen Typ geeignet ist. Um dies zu erreichen, müssen Sie enable_if auf den Rückgabetyp und nicht auf ein Standardschablonenargument verschieben (da Standardschablonenargumente nicht Teil der Signatur einer Funktion sind und daher nicht zum Überladen verwendet werden können, sondern nur mit SFINAE eingeschränkt werden ). Diese Lösung wird für viele Überladungen nicht funktionieren, außer Sie können für jede Überladung ein separates Prädikat (d. H. Eine Kombination von Typenmerkmalen) erstellen, sodass keiner der Argumenttypen mit mehr als einem Prädikat übereinstimmt. Dies bedeutet, dass die Prädikate sich gegenseitig ausschließen müssen. Sie können nicht ein Prädikat testen lassen, das ein Konzept wie signed integral type ist, das eine verfeinerte Version eines anderen ist, das ein Konzept wie integral type , weil beide Prädikate für int wahr wären und mehr als eine Funktion aktiviert wäre.

Ein wichtiger Grund, dass C ++ - Konzepte eine bessere Lösung als SFINAE sind, ist, dass Funktionen, die durch Konzepte eingeschränkt sind, geordnet sind, so dass eine eingeschränktere Funktion besser zusammenpasst als eine weniger eingeschränkte. Das bedeutet, dass Sie diese SFINAE-Spiele nicht spielen müssen und sich gegenseitig ausschließende Einschränkungen haben, der Compiler wird das Richtige tun.

    
Jonathan Wakely 28.08.2014, 11:50
quelle
6

Wenden Sie dieselbe SFINAE auf die alternative Methode an, nur die Umkehrung davon (und verschieben Sie sie zum Rückgabetyp); d. h. um den anderen zu deaktivieren.

%Vor%

Sie erwähnen, dass es viele Überladungen geben wird, also kann dies mühsam sein ... Ihre Laufleistung kann variieren.

Hinweis , warum nur 2? Die ursprüngliche Frage war auf 2, aber das Problem hier ist mehr die Reihenfolge zwischen vielen Überladungen mit Template-Einschränkungen. Diese Antwort wird als Beschreibung einer klassischeren Lösung bei nur wenigen Überlastungen (mit überschaubareren SFINAE-Einschränkungen) zurückgelassen.

    
Niall 28.08.2014 11:50
quelle
4

Die einfachste Lösung ist, die zweite Funktion zu deaktivieren, wenn die erste eingeschränkt ist.

Generell können Sie die Überladungsrangfolge verwenden, um eine bestimmte Funktion zu bevorzugen, die besser skaliert. Es ist in etwa so:

%Vor%

Hier muss der Compiler N-Konvertierungen durchführen, um von N auf 0 zu kommen. So können wir Überladungen von N auf 0 rangieren, wobei N am wünschenswertesten und 0 am wenigsten wünschenswert ist.

%Vor%

Nun müssen Sie keine O (n ^ 2) -Dondierung mehr durchführen.

    
Puppy 28.08.2014 11:53
quelle
0

Verschieben Sie enable_if in den Rückgabetyp und verwenden Sie eine inverse Einschränkung.

%Vor%     
Yochai Timmer 28.08.2014 12:31
quelle

Tags und Links