Llamando al constructor con llaves

2 minutos de lectura

Llamando al constructor con llaves
Telar

Pregunta simple sobre la sintaxis de C++ 11. Hay un código de muestra (uno reducido de fuente)

struct Wanderer
{
  explicit Wanderer(std::vector<std::function<void (float)>> & update_loop)
  {
    update_loop.emplace_back([this](float dt) { update(dt); });
  }
  void update(float dt);
};

int main()
{
  std::vector<std::function<void (float)>> update_loop;
  Wanderer wanderer{update_loop}; // why {} ???
}

Me gustaría saber cómo puede ser posible llamar al constructor con corchetes como Wanderer wanderer{update_loop}; No es una lista de inicializadores ni una inicialización uniforme. ¿Qué es esto?

  • Pero es una inicialización uniforme. Las llaves se pueden usar para llamar a los constructores, aunque el constructor toma un std::initializer_list siempre se prefiere ese tipo.

    – chris

    13 mar. 13 a las 20:47


  • // why {} ??? — Buena pregunta. No hay razón para preferir esto a Wanderer wanderer(update_loop).

    – ipc

    13 mar. 13 a las 20:50

  • @ipc En algunos casos, puede evitar el análisis más molesto.

    – juanchopanza

    13 mar. 13 a las 20:51

  • @juanchopanza: Pero en otros casos puede cambiar silenciosamente el significado del código una vez. No soy fanático de la inicialización “uniforme”.

    – ipc

    13 mar. 13 a las 20:53

  • @ipc seguro, esa es una característica bastante fea de esta inicialización.

    – juanchopanza

    13 mar. 13 a las 20:54

Llamando al constructor con llaves
Andy merodea

No es una lista de inicializadores ni una inicialización uniforme. ¿Qué es esto?

Tu premisa es incorrecta. Es una inicialización uniforme y, en términos estándar, inicialización directa de llaves.

A menos que un constructor acepte una std::initializer_list está presente, usar llaves para construir objetos es equivalente a usar paréntesis.

La ventaja de usar llaves es que la sintaxis es inmune a la Análisis más irritante problema:

struct Y { };

struct X
{
    X(Y) { }
};

// ...

X x1(Y()); // MVP: Declares a function called x1 which returns
           // a value of type X and accepts a function that
           // takes no argument and returns a value of type Y.

X x2{Y()}; // OK, constructs an object of type X called x2 and
           // provides a default-constructed temporary object 
           // of type Y in input to X's constructor.

  • “A menos que esté presente un constructor que acepte una std::initializer_list…” ¿Y si tal constructor está presente?

    – junvar

    11 jul.


Es solo sintaxis de C++ 11. Puede inicializar objetos llamando a su constructor con llaves. Solo hay que tener en cuenta que si el tipo tiene un constructor initializer_list, ese tiene prioridad.

.

¿Ha sido útil esta solución?