В C ++ 20 введен явный (bool), который условно выбирает во время компиляции, сделан ли конструктор явным или нет.
Ниже приведен пример, который я нашел здесь .
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
Может ли кто-нибудь сказать мне какой-либо другой вариант explicit (bool)
использования, кроме использования std::is_integral
?
tuple
которых используется эта функция.Ответы:
Сама мотивация видна в статье .
Необходимо сделать конструкторы условно явными. То есть вы хотите:
Первое хорошо, эти конструкторы неявные. Но последнее было бы плохо, эти конструкторы
explicit
. В C ++ 17 (или C ++ 20 с концепциями) единственный способ выполнить эту работу - написать два конструктора - одинexplicit
и один не:Они почти полностью дублируются - и определения этих конструкторов будут идентичны.
С помощью
explicit(bool)
вы можете просто написать один конструктор - с условно явной частью конструкции, локализованной только дляexplicit
-specifier:Это лучше соответствует намерениям, намного меньше кода для написания и меньше работы для компилятора во время разрешения перегрузки (так как между конструкторами приходится выбирать меньше).
источник
enable_if_t
деталь на более симпатичное и более простое ограничение, возможно, с использованием концепций. Но это не относится к этому вопросу.Другое возможное использование, которое я вижу, это с помощью шаблона variadic
Обычно по умолчанию полезно иметь
explicit
конструктор с одним аргументом (если не требуется преобразование).так
источник
Я мог видеть случай использования для
explicit
условного требования, когда входные данные могут иметь вид, подобный представлению (необработанный указательstd::string_view
), который будет удерживать новый объект после вызова (только копирование представления, а не то, к чему он относится, оставаясь зависимым от время жизни просматриваемого объекта), или это может быть тип, подобный значению (становится владельцем копии, без внешних зависимостей времени жизни).В такой ситуации вызывающая сторона отвечает за поддержание живого просматриваемого объекта (вызываемому принадлежит представление, а не исходный объект), и преобразование не должно выполняться неявным образом, поскольку это делает слишком неявно созданным объект слишком простым для пережить объект, который он рассматривает. Напротив, для типов значений новый объект получит свою собственную копию, поэтому, хотя копия может быть дорогостоящей, она не сделает код неправильным, если произойдет неявное преобразование.
источник