J'ai le code suivant:
DString Experiment::FullShotPath(DString &relativepath);
(et "relativepath" est modifié dans la fonction) puis
void *Experiment::GetDataptr(const DString &name, DataType dType, DataAccess dAccess)
{
//First get the full data name
DString FileName;
size_t iLPos = name.RFind('\\');
[...]
FileName = FullShotPath(name.Left(iLPos));
Lorsque je compile, j'ai le message
Experiment.cpp: In member function `void* Experiment::GetDataptr(const DString&, DataType, DataAccess)':
Experiment.cpp:277: error: no matching function for call to `Experiment::FullShotPath(DString)'
Experiment.cpp:148: note: candidates are: DString Experiment::FullShotPath(DString&)
Et la, je bloque: j'ai bien essayé de faire mon appel avec "&(name.Left(iLPos))", ça ne marche pas, et je me rend compte que je ne comprend pas la syntaxe "FullShotPath(DString &relativepath)" (pour passer la valeur par addresse, cela devrait etre "DString *relativepath", non?)
Si quelqu'un a des idees...
Mathias
# const?
Posté par ecyrbe . Évalué à 1.
Si c'est le cas... normal...
Si ça renvoit un DString* encore pire...
Bref je pense qu'il faut que tu adapte ta methode au bon type de paramètres.
Si c'est pas ça, donne nous un copie complète de ta classe pour qu'on pointe le problème du doigt...
[^] # Re: const?
Posté par Mathias Bavay (site web personnel) . Évalué à 2.
En effet, la méthode Left() renvoie un const...
Merci beaucoup!
Pour répondre à tous ceux qui s'interrogent sur ma santé metale, non je ne suis pas l'auteur de ce code ! je fais simplement le portage vers Unix d'un code ecrit sous Windows, compilé avec VC++ par quelqu'un dont c'est le premier essais en C++... Que du bonheur!
(en plus, il utilise plein de constructions que mes connaissances limitées en C++ ne parviennent pas a expliquer, plein de choses specifiques a Windows, il re-invente la roue a longueur de journees, ... Et il est persuade que son code est pur C++ et que c'est Unix qui est bizard a ne pas vouloir digerer son code (plein de bugs au demeurrant)).
Et tout les cas, merci beaucoup pour vos réponses !
Mathias
[^] # Re: const?
Posté par ecyrbe . Évalué à 2.
Une bonne pratique est de doubler ses fonctions type get(), l'une qui renvoit un const et l'autre un modifiable (c'est ce que fait la stl à tour de bras pour les méthodes begin() et end() ).
Et ainsi la bonne méthode sera employé si jamais tu la passe à une fonction qui doit modifier l'objet en question, et le compilo pourra rendre certaines méthodes inline automatiquement lorsque l'optimisation est activée.
Ensuite si ta methode appelée ne modifie pas l'objet, essaye toujours de mettre le mot clef 'const' en paramètre. ça evitera souvent des problèmes.
[^] # Re: const?
Posté par lmg HS (site web personnel) . Évalué à 2.
J'ai l'impression en lisant cela que tu t'es contenté de lever le const du type de retour et que cela passe maintenant. Ce qui me parait surprenant. Quelle version de GCC utilises-tu ?
NB: même si cela passe avec un ancienne version de GCC (ou tout autre vieux compilo VC6, SunWSPro 5.4, ...) il ne faut pas s'attendre à ce que cela continue ainsi -- GCC a été patché, VC a dû l'être aussi. Comme je l'ai déjà signalé il n'y a que 3 corrections valables -- et en plus compatibles avec les vieux compilos. Retirer le const n'en est pas une.
-> DString Experiment::FullShotPath(DString const&relativepath) ; si FullShotPath n'altère pas l'objet reçu en paramètre.
-> DString Experiment::FullShotPath(DString relativepath) ; si FullShotPath n'altère pas l'objet reçu en paramètre et que l'on est prêts à payer une copie.
-> Temporaire nommé intermédiaire
Dit autrement, retirer le const ne servira que sur les environnements sur lesquels on n'a pas réalisé de monté de version des compilos depuis pratiquement 8 ans.
Deux précisions:
- ce n'est pas certains compilos, mais les compilos à jour sur ce point de la norme. Ceux qui ne le sont pas encore le seront très probablement dans le futur,
- que le paramètre temporaire soit const ou pas ne change rien. Une référence ne peut pas être attachée à un temporaire.
Cela ne s'utilise pas dans le même contexte. Si getLeft() renvoie une valeur créée à la volée et ne modifie pas l'objet sur lequel elle est appliqué, alors la fonction doit être const, et renvoyer une copie. Que la copie renvoyée soit const empêche, aujourd'hui, d'appeler des fonctions (membre) non const sur l'objet renvoyé.
Les deux versions de begin() et end() des conteneurs de la SL permettent d'obtenir des itérateurs vers des données modifiables, sauf pour les conteneurs non modifiables qui ne permettent d'obtenir que des itérateurs vers des données itérables non modifiables.
[^] # Re: const?
Posté par ecyrbe . Évalué à 1.
Cependant, qu'une référence constante ne puisse pas être attachée à un temporaire, je trouve ça idiot. Une référence, c'est pour moi un moyen de ne pas faire passer un pointeur comme en C et d'éviter un tas d'assert not null, éviter l'utilisation d'une variable et ainsi d'obtenir un code plus conçis et donc lisible . Si l'objet renvoyé par copie temporaire est passé en référence constante, il me semble logique qu'une variable soit implicitement utilisée par le compilo et ainsi étendre sa durée de vie à l'appel de fonction en retour.
exemple :
void test(const int& i){
....
}
int main(int argc, char* argv[]){
test(3);
}
ça marche avec mon gcc3.4. Donc gcc3.4 n'est pas à jour sur ce point de la norme?
[^] # Re: const?
Posté par lmg HS (site web personnel) . Évalué à 1.
Je voulais bien évidemment parler des "références non-const qui ne peuvent être attachées à des temporaires (non nommés)".
Tout ce que demande la référence const, c'est une convertion implicite entre le type de l'expression (produisant un éventuel temporaire) et le type de la référence-const.
Soit, ton GCC se comporte normalement.
[^] # Re: const?
Posté par Mathias Bavay (site web personnel) . Évalué à 2.
Ouh, loin de moi cette idée!
J'ai en fait modifie FullShotPath() pour que le parametre soit tout d'abord copié avant de travailler sur la copie (qui est utilisé comme une variable temporaire).
Donc maintenant, le parametre est "const", et ce qui devait etre fait reste caché dans la fonction FullShotPath(). (en plus, cela me choquait de modifier le contenu du chemin relatif passé en parametre: cela veux dire que apres un appel a cette fonction, ce chemin est corrompu et inutilisable pour la suite, ce qui est vraiment idiot).
Mathias
PS: en tout les cas, merci pour les explications !
# temporaires non nommés
Posté par lmg HS (site web personnel) . Évalué à 1.
Si elle ne modifie pas ce qu'elle reçoit => "Dstring const&"
Si elle modifie ce qu'elle reçoit => nomme ton temporaire.
Vu que tu programmes en C++, tu sais que tu as tout ce qu'il faut dans boost.file_system pour manipuler des chemins ? (Cela repose sur la classe de chaînes standard std::string)
[^] # Il ne suffit pas de coder en c++
Posté par peck (site web personnel) . Évalué à 2.
[^] # Re: Il ne suffit pas de coder en c++
Posté par lmg HS (site web personnel) . Évalué à 1.
Car c'est typiquement le genre d'endroit où réinventer, et valider, la roue n'a pas un énorme intérêt.
# La methode n'est pas déclarée
Posté par peck (site web personnel) . Évalué à 1.
Mais pour que cela marche il faut pouvoir prendre l'adresse de ce que tu passe en argument. Or ton argument est une valeur temporaire résultat d'un fontion. Tu dois l'affecter a une variable pour pouvoir l'utiliser comme référence.
[^] # Re: La methode n'est pas déclarée
Posté par Obsidian . Évalué à 3.
Un nom de variable n'est qu'une référence à un objet en mémoire, au moment de la compilation. Le retour d'une fonction génère un objet en mémoire à une adresse fixe, et qui peut tout à fait être utilisé comme tel.
Par contre, il se peut que le compilateur (cela dépend des versions, en fait) se plaigne car l'objet, temporaire, n'est pas forcément modifiable. Sémantiquement, cela reste incorrect car le prototype de la fonction imbriquée, lui, est formel.
Avec g++ 3.3, j'obtiens :
Avec
/*
...
*/
#include
class A { public: int x; };
void First (A & a) { a.x == 0; }
A Second (void) { return A(); }
int main (void)
{
First ( Second () );
return 0;
}
[^] # Re: La methode n'est pas déclarée
Posté par lmg HS (site web personnel) . Évalué à 0.
Ce sont les vieux compilos qui acceptaient cela.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.