In C ++ 20 wurde explizit (bool) eingeführt, das beim Kompilieren bedingt auswählt, ob ein Konstruktor explizit gemacht wird oder nicht.
Unten ist ein Beispiel, das ich hier gefunden habe .
struct foo {
// Specify non-integral types (strings, floats, etc.) require explicit construction.
template <typename T>
explicit(!std::is_integral_v<T>) foo(T) {}
};
foo a = 123; // OK
foo b = "123"; // ERROR: explicit constructor is not a candidate (explicit specifier evaluates to true)
foo c {"123"}; // OK
Kann mir jemand einen anderen Verwendungszweck explicit (bool)
als die Verwendung nennen std::is_integral
?
tuple
mit dieser Funktion zu implementieren .Antworten:
Die Motivation selbst ist in der Zeitung zu sehen .
Konstruktoren müssen bedingt explizit gemacht werden. Das heißt, Sie wollen:
Ersteres ist in Ordnung, diese Konstruktoren sind implizit. Aber letzteres wäre schlecht, diese Konstruktoren sind es
explicit
. Mit C ++ 17 (oder C ++ 20 mit Konzepten) können Sie diese Funktion nur ausführen, indem Sie zwei Konstruktoren schreiben - einenexplicit
und einen nicht:Diese sind fast vollständig dupliziert - und die Definitionen dieser Konstruktoren wären identisch.
Mit
explicit(bool)
können Sie einfach einen einzelnen Konstruktor schreiben - wobei der bedingt explizite Teil der Konstruktion nur auf denexplicit
-specifier beschränkt ist:Dies entspricht der Absicht besser, ist viel weniger Code zum Schreiben und weniger Arbeit für den Compiler während der Überlastungsauflösung (da weniger Konstruktoren zur Auswahl stehen).
quelle
enable_if_t
Teil in eine schönere und einfachere Einschränkung zu ändern , möglicherweise unter Verwendung von Konzepten. Aber das ist nicht der Punkt dieser Frage.Eine andere mögliche Verwendung, die ich sehe, ist mit variadic Vorlage:
Standardmäßig ist es im Allgemeinen gut,
explicit
für den Konstruktor nur ein Argument zu haben (es sei denn, die Konvertierung ist erwünscht).damit
quelle
Ich könnte einen Anwendungsfall für das
explicit
bedingte Erfordernis sehen , wenn die Eingabe ein ansichtsähnlicher Typ (Rohzeigerstd::string_view
) sein könnte, an dem das neue Objekt nach dem Aufruf festhalten wird (nur das Kopieren der Ansicht, nicht das, worauf es sich bezieht, bleibt abhängig die Lebensdauer des angezeigten Objekts) oder es kann sich um einen wertähnlichen Typ handeln (übernimmt den Besitz einer Kopie ohne externe Abhängigkeiten zur Lebensdauer).In einer solchen Situation ist der Aufrufer dafür verantwortlich, das angezeigte Objekt am Leben zu erhalten (der Angerufene besitzt eine Ansicht, nicht das ursprüngliche Objekt), und die Konvertierung sollte nicht implizit erfolgen, da dies für das implizit erstellte Objekt zu einfach ist überleben das Objekt, das es sieht. Im Gegensatz dazu erhält das neue Objekt für Werttypen eine eigene Kopie, sodass die Kopie zwar teuer sein kann, der Code jedoch nicht falsch ist, wenn eine implizite Konvertierung erfolgt.
quelle