Ich verwende eine C ++ - Bibliothek ( strf ), die irgendwo darin den folgenden Code enthält:
namespace strf {
template <typename ForwardIt>
inline auto range(ForwardIt begin, ForwardIt end) { /* ... */ }
template <typename Range, typename CharT>
inline auto range(const Range& range, const CharT* sep) { /* ... */ }
}
Jetzt möchte ich strf::range<const char*>(some_char_ptr, some_char_ptr + some_length)
in meinem Code verwenden. In diesem Fall wird jedoch der folgende Fehler angezeigt (mit dem NVCC von CUDA 10.1):
error: more than one instance of overloaded function "strf::range" matches the argument list:
function template "auto strf::range(ForwardIt, ForwardIt)"
function template "auto strf::range(const Range &, const CharT *)"
argument types are: (util::constexpr_string::const_iterator, util::constexpr_string::const_iterator)
Der Bibliothekscode kann wahrscheinlich geändert werden, um dies zu vermeiden (z. B. mit:
inline auto range(const typename std::enable_if<not std::is_pointer<typename std::remove_cv<Range>::type>::value, Range &>::type range, const CharT* sep)
zu gewährleisten Range
ist kein Zeiger); Aber ich kann das jetzt nicht ändern. Stattdessen möchte ich dem Compiler irgendwie anzeigen, dass ich wirklich nur ein Vorlagenargument haben möchte, nicht eines angegeben und ein anderes abgeleitet.
Kann ich das machen?
Würde mich über Antworten für C ++ 11 und C ++ 14 freuen; C ++ 17-Antworten mit Abzugsleitfäden sind weniger relevant. Wenn Sie jedoch eine haben, veröffentlichen Sie diese bitte (für zukünftige NVCC-Versionen ...).
Update: Die strf-Bibliothek selbst wurde aktualisiert, um diese Situation zu umgehen, aber die Frage bleibt wie gestellt.
char*
aber ist einer keine Lösung?Antworten:
Dann rufen Sie
range1
stattstrf::range
.range1_ptr<T>(...)
kann immer verwendet werden, um die Vorlage explizit mit einem Vorlagenargument aufzurufen, führt jedoch keinen Abzug von den Argumenten durch.range1
Repliziert den Abzug von der Originalvorlagestrf::range
.Dies funktioniert, weil [temp.deduct.funcaddr] / 1 besagt, dass die Ableitung von Vorlagenargumenten, wenn die Adresse einer Funktion ohne der Konvertierung verwendet wird, für jede Kandidatenfunktionsvorlage so erfolgt, als ob die Parameter- und Argumentlisten eines hypothetischen Aufrufs wären leeren. Daher kann das zweite Vorlagenargument nicht für die zweite Überladung mit zwei Vorlagenparametern abgeleitet werden. Der einzige verbleibende Kandidat ist die erste Überladung, die als Ziel des Funktionszeigers ausgewählt wird.
Solange es keine zweite Kandidatenfunktionsvorlage gibt, für die eine gültige Vorlagen-ID mit nur einem Argument gebildet werden
range1_ptr
kann , kann immer verwendet werden, um die Funktionsvorlage mit einem Argument eindeutig aufzurufen. Andernfalls führt die Instanziierung vonrange1_ptr
aufgrund von Mehrdeutigkeiten zu einem Fehler.quelle
strf::range<T>
?pretty_please_with_sugar_on_top()
? ... C ++ kann manchmal so komisch sein ...Was ist mit einem Durchgang durch ein
using
?quelle
range()
Version kompatibel isttpf
; anderer Fall kann anders sein.tfp x = &strf::range<char const *>;
) erläutern . Auf diese Weise haben Sie vermutlich eine allgemeine Lösung, die fast der der Walnuss entsprichtEine Lösung ist
1) Zunächst sollten Sie den Typ für das zweite Argument angeben, z
(char *)(some_char_ptr + some_length)
2) nicht
const
für beide verwenden, das funktioniert gut:Sie können versuchen , zu ersetzen ,
(char *)
mit(const char *)
links oder rechts an, es funktioniert immer noch.quelle
const
Daten verweisen .