El primer formulario data de la hora C, mientras que el segundo se agregó en C++. La razón para la adición es que en algunos contextos (en particular listas de inicializadores en constructores) no se permite el primer formulario.
Los dos no son exactamente equivalentes para todos los tipos, y es allí donde uno u otro podrían ser más útiles. La primera forma semánticamente implica la creación de un temporal desde el lado derecho, seguido de la construcción de la copia de la variable desde ese temporal. La segunda forma es la inicialización directa de la variable del argumento.
¿Cuándo importa?
El primer formulario fallará si no hay una conversión implícita desde el lado derecho al tipo de la variable, o si el constructor de copia no está disponible, por lo que en esos casos deberá usar la inicialización directa.
La segunda forma puede ser utilizado en más contextos que el primero, pero que es propenso a la más-irritante-analizar. Es decir, en algunos casos la sintaxis será compatible con una declaración para una función (en lugar de la definición de una variable regular), y el lenguaje determina que cuando este es el caso, la expresión se debe analizar como una declaración de función:
std::string s = std::string(); // ok declares a variable
std::string s(std::string()); // declares a function: std::string s(std::string(*)())
Finalmente en C++ 11 hay una tercera forma, que utiliza llaves:
std::string s{std::string{}};
Esta forma tiene las ventajas de inicialización directo con paréntesis, pero al mismo tiempo no es propenso a la mala interpretación.
¿Cuál usar?
Recomendaría la tercera opción si está disponible. Dicho eso, tiendo a usar el primero más de las veces, o el segundo dependiendo del contexto y los tipos ...
Para que lo sepas, si lo pruebas en tu propio tipo, 'MyClass obj = 5; 'llama al constructor y nunca al operador de asignación. También sé que esto se ha preguntado antes; Trataré de encontrar dónde fue. – chris
Técnicamente, ninguno de estos son asignaciones. Son * inicializaciones *. Definen e inicializan una nueva variable. La asignación se produce cuando asigna un nuevo valor a una variable existente. ('int i = 1' es inicialización, pero' i = 2' es asignación) – jalf