2011-12-13 4 views
5

Sto cercando di trovare un elemento in un vettore di strutture. Il codice funziona quando si cerca in modo sensibile al maiuscolo/minuscolo. Quando cerco di migliorare la distinzione tra maiuscole e minuscole, mi imbatto in due problemi.Uso di boost phoenix, come posso richiamare una chiamata find_if con starts_with?

  1. Semplicemente compresa boost/algorithm/string.hpp rompe il VS2010 in precedenza lavorando compilazione. L'errore è "'boost :: phoenix :: bind': chiamata ambigua alla funzione sovraccaricata". Crea OK in Xcode. Un modo per disambiguare il legame?

  2. Suppongo di aver sbagliato la sintassi nella seconda (commentato) riga find_if, aggiungendo l'istarts_with call. Ottengo errori dalle intestazioni phoenix dicendo "errore: nessun tipo di nome 'tipo'". Supponendo che il numero 1 possa essere corretto, come devo correggere questa riga?

Grazie!

Codice:

#include <iostream> 
#include <algorithm> 
#include <string> 
#include <vector> 
#include <boost/algorithm/string.hpp> // This include breaks VS2010! 
#include <boost/phoenix/bind.hpp> 
#include <boost/phoenix/core.hpp> 
#include <boost/phoenix/operator.hpp> 
#include <boost/phoenix/stl/algorithm.hpp> 
using namespace boost::phoenix; 
using boost::phoenix::arg_names::arg1; 
using boost::istarts_with; 
using std::string; 
using std::cout; 

// Some simple struct I'll build a vector out of 
struct Person 
{ 
    string FirstName; 
    string LastName; 
    Person(string const& f, string const& l) : FirstName(f), LastName(l) {} 
}; 

int main() 
{ 
    // Vector to search 
    std::vector<Person> people; 
    std::vector<Person>::iterator dude; 

    // Test data 
    people.push_back(Person("Fred", "Smith")); 

    // Works! 
    dude = std::find_if(people.begin(), people.end(), bind(&Person::FirstName, arg1) == "Fred"); 
    // Won't build - how can I do this case-insensitively? 
    //dude = std::find_if(people.begin(), people.end(), istarts_with(bind(&Person::FirstName, arg1), "Fred")); 

    if (dude != people.end()) 
     cout << dude->LastName; 
    else 
     cout << "Not found"; 
    return 0; 
} 
+0

Quale versione di Boost stai usando? – MDman

+0

Utilizzo di Boost 1.48.0. –

risposta

2

Avresti bisogno di due lega per farlo funzionare. In primo luogo definire:

int istw(string a, string b) { return istarts_with(a,b); } 

e quindi utilizzare il seguente come il predicato per la find_if:

bind(&istw,bind(&Person::FirstName, arg1),"fred") 

Due osservazioni:

  1. Assicurarsi che si sta utilizzando il diritto bind, vale a dire, utilizzare boost::phoenix::bind.
  2. La definizione di istw non è probabilmente necessaria ma non sono riuscito a trovare il modo corretto per sostituirlo.
+0

Non avevo provato a spostare l'istarts_iwith in una funzione separata, e questo in effetti è il trucco. Grazie! –

+0

Il problema con VS2010 che non lo compila esiste ancora, ma ora posso spostare istw in un file separato che include boost/algorithm/string.hpp e lasciare questo file incluso phoenix. –

+0

Penso che saresti in grado di compilare se usassi esplicitamente 'boost :: phoenix :: bind' (che non richiede alcuna disambiguazione) invece di usare solo' bind' – MDman