C ++ 20 wprowadził jawne (bool), które warunkowo wybiera w czasie kompilacji, czy konstruktor jest jawny, czy nie.
Poniżej znajduje się przykład, który znalazłem tutaj .
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
Czy ktoś może mi powiedzieć inny przypadek explicit (bool)
użycia niż użycie std::is_integral
?
tuple
z tą funkcją.Odpowiedzi:
Sama motywacja znajduje się w artykule .
Istnieje potrzeba, aby konstruktory były warunkowo jawne. Oznacza to, że chcesz:
To pierwsze jest w porządku, te konstruktory są ukryte. Ale to drugie byłoby złe, ci konstruktorzy są
explicit
. W C ++ 17 (lub C ++ 20 z koncepcjami) jedynym sposobem na wykonanie tej pracy jest napisanie dwóch konstruktorów - jednegoexplicit
i jednego nie:Są one prawie całkowicie zduplikowane - a definicje tych konstruktorów byłyby identyczne.
Za pomocą
explicit(bool)
możesz napisać tylko jednego konstruktora - z warunkowo jawną częścią konstrukcji zlokalizowaną tylko naexplicit
-specifier:To lepiej pasuje do zamiaru, jest o wiele mniej kodu do napisania i jest mniej pracy dla kompilatora podczas rozwiązywania problemu przeciążenia (ponieważ jest mniej konstruktorów do wyboru).
źródło
enable_if_t
części na ładniejsze i prostsze ograniczenie, prawdopodobnie przy użyciu pojęć. Ale to nie ma znaczenia w tym pytaniu.Innym możliwym zastosowaniem, jaki widzę, jest szablon variadic:
Ogólnie dobrze jest mieć domyślnie
explicit
dla konstruktora tylko jeden argument (chyba że pożądana jest konwersja).więc
źródło
Widziałem przypadek użycia
explicit
warunku wymagającego warunku, kiedy dane wejściowe mogą być typu widoku (surowy wskaźnikstd::string_view
), który nowy obiekt zachowa po wywołaniu (tylko kopiowanie widoku, a nie tego, do którego się odnosi, pozostanie zależne od czas życia oglądanego obiektu) lub może to być typ podobny do wartości (przejmuje własność kopii, bez zewnętrznych zależności czasu życia).W takiej sytuacji osoba wywołująca jest odpowiedzialna za utrzymanie oglądanego obiektu przy życiu (odbiorca jest właścicielem widoku, a nie obiektu oryginalnego), a konwersja nie powinna być wykonywana w sposób niejawny, ponieważ ułatwia to niejawnie utworzonemu obiektowi przeżyj oglądany obiekt. Natomiast w przypadku typów wartości nowy obiekt otrzyma własną kopię, więc chociaż kopia może być kosztowna, nie spowoduje błędu kodu, jeśli nastąpi niejawna konwersja.
źródło