C ++ 20 introdujo explícito (bool) que selecciona condicionalmente en tiempo de compilación si un constructor se hace explícito o no.
A continuación se muestra un ejemplo que encontré aquí .
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
¿Alguien puede decirme algún otro caso explicit (bool)
de uso que no sea el uso std::is_integral
?
tuple
con esta característica.Respuestas:
La motivación en sí misma se puede ver en el documento .
Es necesario hacer que los constructores sean condicionalmente explícitos. Es decir, quieres:
Lo primero está bien, esos constructores están implícitos. Pero esto último sería malo, esos constructores lo son
explicit
. Con C ++ 17 (o C ++ 20 con conceptos), la única forma de hacer que esto funcione es escribir dos constructores, unoexplicit
y otro no:Estos están casi completamente duplicados, y las definiciones de estos constructores serían idénticas.
Con
explicit(bool)
, puede escribir un solo constructor, con la parte condicionalmente explícita de la construcción localizada solo en elexplicit
especificador:Esto coincide mejor con la intención, es mucho menos código para escribir y es menos trabajo para el compilador durante la resolución de sobrecarga (ya que hay menos constructores para elegir).
fuente
enable_if_t
parte a una restricción más bonita y simple, posiblemente utilizando conceptos. Pero eso no viene al caso en esta pregunta.Otro posible uso que veo es con una plantilla variadic:
Generalmente es bueno, por defecto, tener
explicit
un constructor con un solo argumento (a menos que se desee la conversión).entonces
fuente
Pude ver un caso de uso para requerir
explicit
condicionalmente cuando la entrada podría ser un tipo de vista (puntero sin formatostd::string_view
) al que el nuevo objeto se aferrará después de la llamada (solo copiando la vista, no a lo que se refiere, dependiendo de la vida útil del objeto visto), o podría ser un tipo de valor (toma posesión de una copia, sin dependencias externas de por vida).En una situación como esa, la persona que llama es responsable de mantener vivo el objeto visto (la persona que llama posee una vista, no el objeto original), y la conversión no debe hacerse implícitamente, porque hace que sea demasiado fácil para el objeto creado implícitamente Sobrevive al objeto que ve. Por el contrario, para los tipos de valor, el nuevo objeto recibirá su propia copia, por lo que si bien la copia puede ser costosa, no hará que el código sea incorrecto si se produce una conversión implícita.
fuente