studio - C++ siempre usa constructor explícito
solidity español (1)
Después de leer el siguiente blog:
http://xania.org/200711/ambiguous-overloading
Comencé a preguntarme "¿no debería siempre definir explícitamente a mis constructores?"
Así que empecé a leer más de lo que descubrí en este artículo:
http://www.sjbrown.co.uk/2004/05/01/always-use-explicit/
Lo que muestra otro ejemplo, y también explica sus pensamientos detrás de él. Pero, por supuesto, este es el pensamiento de un blogger.
Me encantaría saber de algunos de ustedes, cuál es su opinión sobre la manera, cuál es su experiencia con el tema y algunos ejemplos, de cualquier manera, sería bueno.
La sabiduría tradicional es que los constructores que toman un parámetro (explícita o efectivamente mediante el uso de parámetros predeterminados) deben marcarse explicit
, a menos que definan una conversión ( std::string
convertible de const char*
es un ejemplo de este último). Usted mismo ha descubierto las razones, ya que las conversiones implícitas pueden hacer la vida más difícil de lo que tiene que ser.
Una excepción quizás obvia a eso sería el constructor de copia. O quizás otra forma es considerar que la mayoría de los tipos son convertibles desde y hacia sí mismos, y que, como tal, el constructor de copias no está marcado explicit
mayor parte del tiempo.
Si bien puede parecer que marcar explicit
todos los demás tipos de constructores no hace daño, lo defiendo. Porque mientras explicit
no tiene efecto en un constructor que toma múltiples argumentos en C ++ 03, sí tiene un efecto en C ++ 11. Para ponerlo en codigo:
struct foo {
explicit foo(int i);
foo(int i, int j);
explicit foo(int i, int j, int k);
};
foo make_foo()
{
/* Not C++11-specific: */
// Error: no conversion from int to foo
return 42;
// Okay: construction, not conversion
return foo(42);
// Okay: constructions
return foo(42, 42);
return foo(42, 42, 42);
/* C++11 specific: */
// Error: no conversion from int to foo
return { 42 };
// Not an error, not a conversion
return { 42, 42 };
// Error! Constructor is explicit
return { 42, 42, 42 };
// Not an error, direct-initialization syntax
return foo { 42, 42, 42 };
}
Personalmente, me parece innecesariamente detallado que en una función que devuelve foo
tengo que devolver explícitamente foo { 42, 42, 42 }
. No veo de qué me está protegiendo explicit
. Realmente quiero que la sintaxis de { initializers... }
signifique ''construir objeto a partir de inicializadores dados'', y explicit
interpone en el camino de eso sin que me ahorre nada. (Dado que { i }
reduce a i
en el contexto de la inicialización de la copia, la mayoría de las veces, con mucho gusto lo dejaré).
Así que yo diría que adquiera el hábito de usar explicit
para constructores únicos , y solo eso .