2010-11-11 12 views
3

J'essaie d'utiliser boost :: regex_replace avec un formateur personnalisé. Je dois passer une méthode à partir d'un objet car un membre est nécessaire dans la fonction de remplacement.booster formateur personnalisé en utilisant boost bind à la méthode en prenant un seul paramètre

La signature de ma méthode remplaçant est:

std::string MyObject::ReplaceStr(
    boost::match_results<std::string::const_iterator> match) const 

Lorsque vous appelez regex_replace, je passe ces arguments:

std::string replaced = regex_replace(
    orig_string, replace_pattern, 
    boost::bind<std::string>(&MyObject::ReplaceStr, this, _1)); 

Le problème est quand regex_replace appelle la méthode de format sur le résultat du match, la Functor utilisé est celui qui prend 3 paramètres (le formateur personnalisé peut être une chaîne, unaire, une fonction binaire ou ternaire). Je pense que c'est dû au fait que boost :: bind cache quelque peu l'arité d'une fonction.

La raison pour laquelle je pense qu'il est dû à la disparition du arité est parce que lors de la liaison avec

std::string replaced = regex_replace(
    orig_string, replace_pattern,  
    std::bind1st(std::mem_fun(&MyObject::ReplaceStr), this)); 

foncteur droit (celui qui utilise la fonction unaire) est appelée.

Je pourrais aussi probablement utiliser une fonction ternaire dans mon objet pour lier et alors cela fonctionnerait probablement mais pour comprendre et utiliser boost :: bind quelqu'un peut-il m'expliquer si j'ai bien compris et si ce n'est pas le bon explication.

Point bonus si je peux le faire fonctionner avec boost bind.

EDIT: J'ai oublié de dire qu'il se bloque lorsque j'utilise boost::bind en raison de la sélection de la mauvaise signature de méthode. Voici un extrait de code pour reproduire le comportement que j'ai essayé d'expliquer:

using namespace std; 
using namespace boost; 

class MyObject 
{ 
public: 
    void ReplacePattern() 
    { 
     const std::string testString = "${value_to_replace}extra_value"; 

     boost::regex replace_pattern("(\\$\\{(.*?)\\})"); 
     std::string replaced = regex_replace(testString, replace_pattern, boost::bind(&MyObject::ReplaceStr, this, _1)); 

     cout << "Replaced: " << replaced << endl; 
    } 

    std::string ReplaceStr(
     boost::match_results<std::string::const_iterator> match) const 
    { 
     return "replaced_value"; 
    } 
}; 


int main(int argc, char* argv[]) 
{ 
    MyObject obj; 
    obj.ReplacePattern(); 


    char dummy[1]; 
    cin.getline(dummy, 1); 

    return 0; 
} 
+0

Pouvez-vous ajouter un exemple de code pour reproduire votre problème? J'ai essayé de le comprendre mais je ne le comprends pas vraiment. Votre utilisation 'boost :: bind' me semble bien, et tant qu'il n'y a qu'un seul espace réservé, le foncteur résultant devrait être une fonction unaire que le compilateur ne permettrait pas d'appeler avec 3 paramètres. – icecrime

+0

Exemple de code ajouté. –

Répondre

2

Vous pouvez utiliser boost :: fonction pour éviter toute ambiguïté:

boost::function<std::string (boost::match_results<std::string::const_iterator>)> function = 
    boost::bind(&MyObject::ReplaceStr, this, _1); 
std::string replaced = regex_replace(testString, replace_pattern, function); 
+0

Je me sens un peu honteux de l'intelligence de cette réponse mais ça fonctionne parfaitement. Gloire. –

Questions connexes