Ich spezialisiere std::common_type
für meinen Typ. Ich habe folgende Spezialisierung definiert:
Und alles ist gut. Dann kommt jemand vorbei und ruft std::common_type<my_type, my_type &>
auf. Die Standardversion verhält sich genauso, wenn Sie eine Referenz im Gegensatz zu einer Referenz übergeben (da sie std::decay
für die Typen aufruft). Es wird jedoch nicht auf die Nicht-Referenzversion von std::common_type
verwiesen, die ich korrekt arbeiten müsste. Gibt es einen besseren Weg als etwas zu tun (r-Wert-Verweis auf const zur Vereinfachung weglassen):
Sicherlich gibt es einen besseren Weg? Nach meiner Zählung sind das 49 mögliche Versionen, wenn wir const &&
und const volatile &&
Hinweis: my_type ist eigentlich eine Klassenvorlage, daher sieht die Spezialisierung eher wie
aus %Vor% Wo das Ergebnis my_type<min(lhs_min, rhs_min), max(lhs_max, rhs_max)>
Die Lösung wäre ziemlich einfach, wenn ich volle Kontrolle über die primären Template-Definitionen hätte, aber ich kann natürlich std::common_type
nicht ändern.
Soweit ich weiß, müssen Sie nicht beide Seiten der Binärdatei common_type
vollständig spezialisieren. Dies ermöglicht die Reduzierung der Spezialisierung auf 12 für eine Seite. Wenn Sie nur einen gemeinsamen Typ zwischen Spezialisierungen von my_type
und my_type
benötigen, reicht es aus, auf einer Seite zu spezialisieren. Andernfalls müssten Sie sie auf der rechten Seite klonen und 24 Spezialisierungen ergeben.
Ich würde vorschlagen, die Spezialisierung ohne die cv- und ref-Qualifiers zu schreiben,
und verwende einen Wrapper um std::common_type<>
, wie folgt:
Es gibt bereits Spezialisierungen für std::chrono::duration
und std::chrono::time_point
, die sich nur ohne cv- und ref-Qualifikatoren spezialisieren.
Diese Spezialisierungen werden jedoch nur verwendet, wenn cv- und ref-Qualifikationsmerkmale nicht angegeben sind. Es ist nicht offensichtlich, dass sie nicht verwendet werden, weil
%Vor%funktioniert gut.
Ich war verwirrt darüber, wie die Spezialisierung verwendet wurde, bis mir klar wurde, dass das nicht der Fall war. Die generische Implementierung von std::common_type<>
verwendet decltype()
für einen if-else-Ausdruck wie folgt:
Hinweis : Es verwendet SFINAE, um dieses auszuwählen, wenn es erfolgreich ist, andernfalls wird der Typ nicht definiert.
Nun können wir testen, ob dies tatsächlich für std::chrono::duration
funktioniert, indem Sie es testen,
was passiert. Jetzt werfen Sie volatile
hinein und es bricht ab, genau wie @ Vincent darauf hingewiesen hat, was wiederum beweist, dass die Spezialisierungen nicht verwendet werden.
Also meine Schlussfolgerung ist, dass einer der beiden passieren wird:
CommonType<>
-Wrapper wegwerfen, der sowieso trivial ist und den Sie nur definiert haben eine Spezialisierung. CommonType<>
verwendet. Tags und Links c++ c++11 templates template-meta-programming template-specialization