5

Estoy haciendo una aplicación de servidor simple en C++, es decir, utilizo libconfig ++ para analizar mis archivos de configuración. Bueno, libconfig no es compatible con multihilo, por lo que estoy usando dos clases de contenedor para lograr "soporte". El punto es, uno de ellos falla:Weird "candidato espera 1 argumento, 0 proporcionado" en el constructor

class app_config { 
    friend class app_config_lock; 
public: 
    app_config(char *file) : 
     cfg(new libconfig::Config()), 
     mutex(new boost::mutex()) 
    { 
     cfg->readFile(file); 
    } 

private: 
    boost::shared_ptr<libconfig::Config> cfg; 
    boost::shared_ptr<boost::mutex> mutex; 
}; 

falla terriblemente cuando se llama desde mi archivo main.cpp:

app_main::app_main(int c, char **v) : argc(c), argv(v) { 
    // here need code to parse arguments and pass configuration file!. 
    try { 
     config = app_config("mscs.cfg"); 
    } catch (libconfig::ParseException &e) { 
     cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl; 
     throw; 
    } catch (libconfig::FileIOException &e) { 
     cout << "Configuration file not found." << endl; 
     throw; 
    } 
} 

y dice:

main.cpp: In constructor ‘app_main::app_main(int, char**)’: 
main.cpp:38:54: error: no matching function for call to ‘app_config::app_config()’ 
main.cpp:38:54: note: candidates are: 
../include/app_config.h:15:5: note: app_config::app_config(char*) 
../include/app_config.h:15:5: note: candidate expects 1 argument, 0 provided 
../include/app_config.h:12:7: note: app_config::app_config(const app_config&) 
../include/app_config.h:12:7: note: candidate expects 1 argument, 0 provided 
main.cpp:41:39: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings] (THIS CAN BE IGNORED, I WAS USING STD::STRING, YET CHANGED IT FOR TESTING PURPOSES) 

lo cual es raro porque yo m claramente pasando una discusión, y además es un char *!

Bueno, como siempre, cualquier ayuda será apreciada.

Julian.

Respuesta

10

Está tratando de construir por defecto su configuración, y luego asignarla a ella más tarde. Pero no tienes un constructor predeterminado.

La forma correcta de pasar un argumento al constructor de una variable miembro es:

app_main::app_main(int c, char **v) : argc(c), argv(v), config("mscs.cfg") 

Todavía puede atrapar la excepción, mediante el uso de lo que se conoce como una función de tratar bloque. Ver http://www.gotw.ca/gotw/066.htm

código final:

app_main::app_main(int c, char **v) 
try : argc(c), argv(v), config("mscs.cfg") 
{ 
    // more constructor logic here 
} catch (libconfig::ParseException &e) { 
    cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl; 
    throw; 
} catch (libconfig::FileIOException &e) { 
    cout << "Configuration file not found." << endl; 
    throw; 
} 
+0

Esto resolvió el problema. Sin embargo, planeo pasar una cadena variable, en lugar de una cadena estática, ¿hay alguna manera de que realmente pueda procesar mis variables argc y argv dentro de mi miembro app_main e inicializar la configuración después de eso, en lugar de en la lista de inicialización? –

+1

@JulianBayardoSpadafora: No. Puede pasar los argumentos del constructor a los constructores miembros, no solo las constantes en tiempo de compilación. Y también puede llamar a las funciones estáticas de los miembros dentro de * ctor-initializer-list *. Finalmente, usted tiene control sobre el orden en que se construyen los miembros. Pero probablemente deba hacer un procesamiento de argumentos antes de esto, y pasar algún tipo de objeto paquete de opción con un 'getConfigFilename()' o dicha función de miembro. O simplemente dele a 'app_config' una función para leer el archivo en lugar de hacerlo desde el constructor. –

4

En primer lugar, no asignan dinámicamente mutex, no sirve para nada. En segundo lugar, es porque tiene un miembro de datos que no puede construirse por defecto, y no lo inicializó en la lista de inicio de ctor. Además, nunca asigne literales de cadena a las variables char* (debe ser app_config(const char*) si realmente desea explorar con punteros de char).

Su app_main::app_main debería tener este lugar:

app_main::app_main(int c, char **v) try 
    : argc(c), argv(v), config("mscs.cfg") { 
} catch (libconfig::ParseException &e) { 
    cout << "Parse error at line " << e.getLine() << ": " << e.getError() << endl; 
    throw; 
} catch (libconfig::FileIOException &e) { 
    cout << "Configuration file not found." << endl; 
    throw; 
} 
Cuestiones relacionadas