2011-10-19 7 views
14

Mam struct tak:Korzystanie bind1st do metody, która bierze argumentu przez odniesienie

struct A { 
    void i(int i) {} 
    void s(string const &s) {} 
}; 

Teraz, gdy próbuję to:

bind1st(mem_fun(&A::i), &a)(0); 
bind1st(mem_fun(&A::s), &a)(""); 

Pierwsza linia kompiluje OK, ale drugi generuje błąd:

c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(299): error C2535: 'void std::binder1st<_Fn2>::operator()(const std::basic_string<_Elem,_Traits,_Ax> &) const' : member function already defined or declared 
      with 
      [ 
       _Fn2=std::mem_fun1_t<void,A,const std::string &>, 
       _Elem=char, 
       _Traits=std::char_traits<char>, 
       _Ax=std::allocator<char> 
      ] 
      c:\program files (x86)\microsoft visual studio 10.0\vc\include\xfunctional(293) : see declaration of 'std::binder1st<_Fn2>::operator()' 
      with 
      [ 
       _Fn2=std::mem_fun1_t<void,A,const std::string &> 
      ] 
      c:\work\sources\exception\test\exception\main.cpp(33) : see reference to class template instantiation 'std::binder1st<_Fn2>' being compiled 
      with 
      [ 
       _Fn2=std::mem_fun1_t<void,A,const std::string &> 
      ] 

Co może być problemem? Jak mogę to naprawić?

Edit:

Wydaje się, że każda teza odniesienia jest problem. Więc jeśli zmienię metodę i na void i(int &i) {}, otrzymam podobny błąd.

+0

Biorąc pod uwagę, że jesteśmy w 2011 roku i ma C++ 11 może chcesz przyjrzeć się C++ std :: '11s bind' lub' boost :: wiążą 'które sprawiają, że te rzeczy o rząd wielkości są łatwiejsze w obsłudze. – PlasmaHH

+1

@PlasmaHH: Niestety, nie mogę używać C++ 11 w tym projekcie. –

+0

A także "boost :: bind"? – PlasmaHH

Odpowiedz

10

std :: bind1st i std :: bind2nd nie akceptują funktorów, które pobierają argumenty odwołań, ponieważ same tworzą odwołania do tych argumentów. Można

  1. użyć wskaźników dla swoich wejść funkcyjnych zamiast odniesień
  2. wykorzystanie boost :: wiążą
  3. przyjąć koszt wydajności kopiowania o jakieś
0

Spójrz na to post były wymagania parametry szablonów są wyjaśnione. Jak już założyłeś, problemem jest odwołanie do std :: string. To nie jest poprawny parametr szablonu.

+1

Chociaż jest to prawda, typ argumentu funkcji jest przenoszony z mem_fun do bind1st przez typ_argumentu first_argument_type, a odwołanie jest poprawnym typedef. Tak więc std :: bind1st * może * teoretycznie akceptować referencje, ale jest realizowany inaczej (a implementacja ta jest wymagana przez standard, IIRC). – thiton

0

Zmiany odniesienia według wskazówek

#include <functional> 
#include <string> 

struct A { 
    void i(int i) {} 
    void s(const std::string *s) {} 
}; 


int main(void) 
{ 
    A a; 
    std::bind1st(std::mem_fun(&A::i), &a)(0); 
    const std::string s(""); 
    std::bind1st(std::mem_fun(&A::s), &a)(&s); 
} 
Powiązane problemy