[résolu]xcode c++ "void funct ()()();"
Bonjour
Yosemite - Xcode 6 - wxWidgets 3 - PostgreSQL 9.3 - libpqxx 4
Mon application est écrite en C++ (utilisation de wxWidgets en vue de portage ...) .
Donc il m'a semblé cohérent d'utiliser l'inteface C++ (libpqxx) pour la gestion de ma base PG.
J'ai un peu de mal !
Je veux utiliser la classe (?) "prepare" de libpqxx.
J'ai trouvé http://stackoverflow.com/questions/16047986/how-to-insert-binary-data-into-a-postgresql-bytea-column-using-the-c-libpqxx-a qui semble répondre à mon objectif
L'instruction (structure) qui m'intéresse :
string prepName = "essai0"
reqSqlWithParms = "select * from $1";
string typeSql = "varchar";
connection *conn;
conn->prepare(prepName, reqSqlWithParms) (typeSql, treat_string);
^
Message d'erreur Xcode :
Called object type 'void' is not a function or function pointer
D'après ce que j'ai compris le bloc en erreur sert à définir le type du paramètre $1. C'est une syntaxe pas absurde à priori (rappelle un peu l'appel des paramètres d'une méthode de l'ObjC), syntaxe que je ne connais pas, mais que le compilateur standard avec la librairie standard associée ne connaà®t pas lui non plus.
Si je supprime ce bloc en conservant le paramère "$1", j'ai une autre erreur assez logique :
ERROR: syntax error at or near "$1"
LINE 1: select * from $1;
J'ai vu cette syntaxe à plusieurs reprises pour la classe "prépare", mais la doc de libpqxx que j'utilise ne le prévoit pas. D'ailleurs Xcode ne la propose pas dans la complétion automatique.
Lorsque je supprime le paramètre "$1" et le bloc qui le définit, tout se passe bien...
Quelqu'un aurait-il une idée ?
Merci.
Réponses
Premier problème, le type de reqSqlWithParms n'est pas défini. Le compilateur ne peut pas le deviner.
Ensuite, prepare c'est pas une class, mais une méthode de la classe connection. Le code ci-dessus va planter à coup sur, puisqu'il appelle la méthode prépare sur un object de type connection (pointeur conn) qui n'a jamais été créé.
Enfin, les appels de méthodes en C++ sont syntaxiquement identiques à des appels de fonction en C. Donc ce qui est écrit ici ne peut fonctionner que si la méthode prepare retourne un pointeur sur fonction prenant 2 paramètres (et encore je ne suis pas certain que ca fonctionne tel quel à cause de la précédence des opérateurs) ou un objet surchargeant l'opérateur () (Parce que oui, en C++ on peut surcharger l'opérateur d'appel de méthodes...).
Ce qui n'est manifestement pas le cas puisque prepare semble retourner void (qui, comme en C, ne veut dire retourne rien).
En l'occurrence, dans les exemples de StackOverflow, c'est la méthode prepared qui est appelée avec cette syntaxe, pas prepare (et je suis presque certain qu'elle retourne un objet surchargeant () ).
Conclusion : Ce code ressemble à tout sauf à du C++ valide xd
Edit : Finalement, le C++ c'est très bien pour écrire du code illisible pour le néophite...
Premier problème : simple oubli d'écriture, il manque le type "string".
Dans les exemples de StackOverflow : c'est bien prepare dans le dernier cas et pas prépared (cf STORING AN wxImage IN DATABASE).
Bon, ça ne change pas grand chose.
Mais il semble bien qu'il s'agisse de code valide.
Tes réflexions m'ont amené à plonger dans le monde du C++ : Le langage C++ de Bjorn Stroustrup. Il y a quelque chose qui existe au chapitre 11 "Surcharge des opérateurs", 11.9 "Appel de fonctions", page 319.
Dans la doc de pqxx sur "pqxx::prepare::declaration Class Reference"
Il n'y a pas de namespace "declaration"
Dans pqxx/prepared_statement.hxx :
Je n'y comprend pas grand chose.
Voici ce que je devine : il faut remplacer "declaration" par "prepare"
Dans le cas du constructeur, ça marche...
Pour le membre qui est apparemment ce qu'il me faut, je ne vois pas quelle syntaxe utiliser ? Ce qui me gêne c'est "const declaration &" : "declaration" me semble faire double emploi avec "operator".
NB :
1 - Si je fais un bête :
work pgWork0(*pgConn0);
const string sql0 = "select * from plante;";
result pgResult0 = pgWork0.exec(sql0);
Ce qui est totalement faux. L'organisation des fichiers sources en C++ est totalement identique à celle d'Objective-C, pour la simple raison que les 2 langages sont basés sur C et reprennent les mêmes concepts de fichier entête (.h, ou parfois .hxx, voir .hpp en C++ mais c'est rare) et fichier(s) source(s) (.m pour Objective-C, .cpp pour C++).
Le code ci-dessus déclare un opérateur "()" sur un objet de type "declaration" (car membre de cette classe) qui prend 2 paramètres de type "const PGSTD::string &" et "param_treatment" (dont un optionnel), et qui retourne un "const declaration &"
C'est, comme je le supposais dés le départ, ce qui permet de chainer des appels ()()()... et résulte en une syntaxe complètement indigeste à mon gout.
Après, je ne connais pas du tout libpqxx, donc je ne vais pouvoir aller bien plus loin. Je n'ai pas le temps non plus de donner des cours de C++, parce que le problème est bien là , la méconnaissance du langage.
Bon, je laisse tomber "prepare".
Oui, je ne connais pas le langage.
Je ne connaissait pas l'Objective C. Il m'a fallu quelques semaines pour y entrer. Et au fil de l'écriture du code, j'ai réussi à obtenir ce que je voulais, avec l'aide de CocoaCafé et avec les recherches sur Google.
Merci d'avoir pris de ton temps pour m'éclairer.