Ist es möglich, eine variadische Version von std::is_convertible
zu schreiben? Zum Beispiel würde are_convertible<T1, T2, T3, T4>
is_convertible<T1, T3> && is_convertible<T2, T4>
zurückgeben. Ich habe einige Stunden darüber nachgedacht, konnte aber nichts Vernünftiges finden.
Um zu verdeutlichen, möchte ich es so verwenden:
%Vor% Sie müssen Args2...
und Args1...
nicht verketten, und Sie sollten es nicht tun, da es macht es unmöglich machen zu sagen, wo Args2...
endet und Args1...
beginnt. Die Möglichkeit, mehrere Variadic-Argumente so zu übergeben, dass sie einzeln extrahiert werden können, besteht darin, sie in eine andere Vorlage einzufügen: Bei einer variadischen Vorlage my_list
könnten Sie Ihre my_convertible
als
Die Standardbibliothek hat bereits eine variadische Vorlage, die hier gut funktioniert: tuple
. Nicht nur das, sondern tuple<Args2...>
ist konvertierbar in tuple<Args1...>
genau dann, wenn Args2...
in Args1...
konvertierbar ist, also können Sie einfach schreiben:
Hinweis: In den Kommentaren berichtet @ zatm8, dass dies nicht immer funktioniert: std::is_convertible<std::tuple<const char *&&>, std::tuple<std::string &&>>::value
wird als false
gemeldet, aber std::is_convertible<const char *&&, std::string &&>::value
wird als true
gemeldet.
Ich glaube, das ist ein Fehler, der beide als true
gemeldet werden sollte. Das Problem ist reproduzierbar auf Ссылка mit clang 3.9.1. Es ist nicht reproduzierbar mit gcc 6.3, und es ist auch nicht reproduzierbar mit clang 3.9.1 bei Verwendung von -stdlib=libc++
. Es scheint, dass libstdc ++ ein Sprachfeature verwendet, das clang nicht ganz korrekt behandelt, und reduziert es auf ein kurzes Beispiel, das nicht auf Standardbibliotheksheadern beruht:
Dies wird von gcc akzeptiert, aber von clang abgelehnt. Es wurde 2014 als Ссылка gemeldet.
Es scheint, dass dies Ende 2016 behoben wurde, aber das Update hat es noch nicht in eine veröffentlichte Version geschafft: Ссылка
Wenn Sie davon betroffen sind, möchten Sie vielleicht std::tuple
vermeiden und stattdessen @ Yakks Antwort verwenden.
Ja.
Erstens, wie es geht. Dann, warum sollten Sie es nicht tun.
Schreibe eine Neugruppierung, die eine Liste von kN Elementen aufnimmt und sie in N Gruppen von k, verschachtelt gruppiert. Gruppen können template<class...>struct types{};
sein.
Dann schreibe apply, das eine template<class...>class Z
und eine class...
der Gruppen (aka types<...>
) nimmt und Z
auf den Inhalt jedes Bundles anwendet, wobei types<...>
des Ergebnisses zurückgegeben wird.
Dann falten Sie den Inhalt von types<...>
mit template<class A, class B> struct and_types:std::integral_constant<bool, A{}&&B{}>{};
.
Ich würde das meistens sinnlos finden, also werde ich es nicht umsetzen. Es sollte einfach mit einer anständigen Metaprogrammierungsbibliothek sein, die meisten der oben genannten Operationen sind Standard.
Aber wirklich, in Ihrem Beispiel, tun Sie das einfach:
%Vor%Dann:
%Vor%erledigt den Job. All das Mischen ist nur Lärm.
Mit der ...
Unterstützung von C ++ 1z werden wir auch and_types
los und benutzen einfach &&
und ...
.
Sie können std :: concuction verwenden, um alle Ergebnistypen in einem zu falten:
%Vor%Und denken Sie daran, zu prüfen, ob
%Vor%mit if conexpr oder enable_if
Tags und Links c++ variadic-templates