Warum enable_if_t in template-Argumente beschwert sich über neudefinitionen?
Ich habe folgenden Fall, der arbeitet mit std::enable_if
:
template<typename T,
typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr>
void f() { }
template<typename T,
typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr>
void f() { }
Nun, ich sah in cppreference die neue syntax, viel sauberer meiner Meinung nach : typename = std::enable_if_t<std::is_same<int, T>::value>>
Ich wollte mein port code :
template<typename T,
typename = std::enable_if_t<std::is_same<int, T>::value>>
void g() { }
template<typename T,
typename = std::enable_if_t<std::is_same<double, T>::value>>
void g() { }
Aber jetzt GCC (5.2) beklagt :
error: redefinition of 'template<class T, class> void g()'
void g() { }
Warum ist das so ? Was kann ich tun, um die neue, prägnante syntax, in diesem Fall, ob das möglich ist ?
- Ihre zweite code verwendet Standard-template-Argumente. Sie sind nicht Teil der Funktionssignatur, damit Sie deklarieren zwei Funktions-templates mit der gleichen Signatur = Neudefinition. Die entsprechende Verwendung von
enable_if_t
ist buchstäblichstd::enable_if_t<std::is_same<int, T>::value>* = nullptr
. - Gut, Sie wusste nicht, schreiben Sie Ihre original-code genau. Sie vergaß die
* = nullptr
. - Sie können fügen Sie eine dummy-template-parameter, um eine der Erklärungen, wie
, typename = void
nachenable_if
- Ich denke, Sie können Ihren Kommentar als Antwort ! @KerrekSB: Nein, das ist der Punkt, der
enable_if_t
@PiotrS. : ok - Wahrscheinlich ein Duplikat von: stackoverflow.com/q/15427667 oder stackoverflow.com/q/28674543 oder stackoverflow.com/q/8743159
- Ich ging die
typename std::enable_if_t<std::is_same<int, T>::value>* = nullptr
route. 4 Zeichen gewonnen, naja :p - Sie brauchen nicht die
typename
vorstd::enable_if_t
. Mehr Zeichen gewonnen. - Noch mehr Zeichen an
std::enable_if_t<std::is_same<int, T>::value, int> = 0
oderstd::enable_if_t<std::is_same_v<int, T>, int> = 0
. - Gerade versucht, aber mein compiler (gcc 4.9) beschwert sich mit
*=0
und nicht mit*=nullptr
. - Das ist, warum ich nicht sagen
*=0
. Ich lieferteint
als zweites argumentenable_if_t
anstelle der Standard -void
, so0
ist ein integer-literal, nicht ein null-Zeiger-literal. - Ich sollte lernen zu Lesen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Lassen Sie uns entfernen Sie einige code.
wären Sie überrascht, wenn der compiler zurückgewiesen, die zwei oben genannten templates?
Beide sind template-Funktionen von "Typ"
template<class,class>void()
. Die Tatsache, dass die 2. Art argument hat eine andere Standard Wert spielt keine Rolle. Das wäre wie erwartet zwei verschiedeneprint(string, int)
Funktionen mit unterschiedlichen Standard -int
Werte zu überlasten. 😉Im ersten Fall haben wir:
hier können wir nicht entfernen Sie die
enable_if
- Klausel. Update aufenable_if_t
:Ich ersetzte auch ein Einsatz von
typename
mitclass
. Ich vermute, deine Verwirrung war, weiltypename
hat zwei Bedeutungen-einer als marker für eine Art vontemplate
argument, und anderen als disambiguator für eine abhängige geben.Hier das 2. argument ist ein pointer, dessen Typ vom ersten abhängig ist. Der compiler kann nicht feststellen, ob diese beiden in Konflikt, ohne zuerst die Substitution in der Art
T
-- und Sie werden feststellen, dass Sie eigentlich nie Konflikte.enable_if_t<B>
ist nur ein alias fürtypename enable_if<B>::type
. Let ' s Ersatz, der ing
so können wir sehen, der wirkliche Unterschied zwischenf
undg
:Im Fall von
f
haben wir zwei Funktions-templates sowohl mit als template-Parameter<typename, X*>
, wo der TypX
ist abhängig auf die Art der ersten Vorlage argument. Im Fall vong
haben wir zwei Funktions-templates mit template-Parametern<typename, typename>
und es ist nur die Standard-template-argument angewiesen ist, also C++ ist der Auffassung, dass Sie sowohl die Deklaration der gleichen Person.Entweder Stil kann verwendet werden, mit der
enable_if_t
alias:Für eine Funktion zurück geben, die Sie suchen, sind die folgenden:
Beispiel:
http://ideone.com/TB36gH
siehe auch
http://ideone.com/EfLkQy
Ihnen fehlt ein "::Typ" ..
std::enable_if_t
ist ein alias Vorlage einer verschachtelten::type
definition vonstd::enable_if