En el siguiente ejemplo de código, quiero inicializar std::string A::str_ en la lista de inicializadores de A con el valor de retorno de una función (que puede devolver NULL) o un {{X3} }. Pero no me gusta el hecho de que Func() se llama dos veces.

#include <iostream>

const char* Func()
{
  char* p = NULL;
  // Assign p: may be NULL or non-NULL
  return p;
}

class A
{
public:
  A() : str_( Func() ? Func() : "NULL" ) {}

  std::string str_;
};

int main( int argc, char* argv[] )
{
  A a;
  std::cout << a.str_ << std::endl;
  return 0;
}

Me gustaría hacer algo como esto:

A() : str_( ( const char*& tmp = Func() ) ? tmp : "NULL" ) {}

Pero usar variables temporales, incluso referencias, para alargar su vida útil, de esta manera parece ilegal (según mi comprensión actual).

¿Existe una sintaxis C ++ 03 que permita la inicialización de A::str_ en la lista de inicializadores, llamando a Func() solo una vez y sin el uso de variables globales / estáticas? Si hay una solución que usa variables temporales, me gustaría aprender su sintaxis.

0
StoneThrow 6 abr. 2017 a las 23:00

2 respuestas

La mejor respuesta

En C ++ 11, use el constructor delegado

class A
{
private:
    A(const char* s) str_(s ? s : "NULL") {}
public:
  A() : A(Func()) {}

  std::string str_;
};

En c ++ 03, cree una función auxiliar

class A
{
private:
    static const char* FuncNotNull() { const char* s = Func(); return s ? s : "NULL"); }
public:
  A() : str_(FuncNotNull()) {}

  std::string str_;
};
4
Jarod42 6 abr. 2017 a las 20:06

Aquí una solución en la que se abusa de una expresión lambda:

A() : str_( ([]()->const char*{ const char* p=Func(); return (p ? p : "NULL"); })() ) {}

De hecho, voté por la respuesta de Jarod. Pero creo que la cosa lambda es tan fea que también quería mostrarla :-)

1
Stephan Lechner 6 abr. 2017 a las 20:22