2015-12-17 9 views
8

Rozważmy następujący:Używanie std :: ptr_fun dla funkcji członka

class A 
{ 
    public: 
    bool is_odd(int i) 
    { 
     return (i % 2) != 0; 
    } 

    void fun() 
    { 
     std::vector<int> v2; 
     v2.push_back(4); 
     v2.push_back(5); 
     v2.push_back(6); 

     // fails here 
     v2.erase(std::remove_if(v2.begin(), v2.end(), std::not1(std::ptr_fun(is_odd))), v2.end()); 
    } 
}; 

Powyższy kod nie neguje efekt is_odd() ponieważ jest to funkcja członkiem. Połączenie z std::ptr_fun() kończy się niepowodzeniem.

Jak mogę to zrobić? Należy pamiętać, że chcę, aby is_odd() była niestatyczną funkcją składową.

+3

Czy funkcja "is_odd' jest statyczna? Czy funkcja nie jest członkiem? Nie ma powodu, dla którego powinna być funkcją członka. –

+0

@HappyCoder: Wykonaj funkcję statycznego członka. –

+0

Możesz napisać klasę funktora, która jest * jak * typ '[this] (int n) {return is_odd (n);}' yourself i użyj tego. –

Odpowiedz

8

Istnieje wiele problemów z użyciem A::is_odd(int) jako jednoargumentowego orzecznika, zwłaszcza, gdy musi być używany z std::not1():

  1. Wywołanie A::is_odd(int) przyjmuje dwa argumenty: ukrytą przedmiot („this”) oraz widoczny argument: int.
  2. Nie jest to obiekt funkcji definiujący argument_type i result_type.

Odpowiednio za pomocą tej funkcji członu jak jednoargumentowy predykatu wymaga dwóch etapów:

  1. dostosowującego wskaźnik funkcji człon poddawany odpowiednim obiektem funkcji, na przykład, za pomocą jednej z funkcji std::mem_*fun.
  2. Powiązanie pierwszego argumentu z odpowiednim obiektem za pomocą kompilatora innego niż C++ 11, prawdopodobnie z użyciem std::bind1st().

Z kompilatorem C++ 11 rzeczy są o wiele łatwiejsze, ponieważ std::bind() zajmie się nimi. Przy założeniu, że stosuje się od członka A:

... std::not1(std::bind(&A::is_odd, this, std::placeholders::_1)) ... 

samo z pre-C++ 11 kompilator twardszy. Zastosowanie w std::remove_if() może wyglądać mniej więcej tak:

v2.erase(
    std::remove_if(v2.begin(), 
        v2.end(), 
        std::not1(std::bind1st(std::mem_fun(&A::is_odd), this))), 
    v2.end()); 
+0

Dobre wykorzystanie 'std :: mem_fun' :-) –

+0

@KerrekSB: tak. Nie zauważyłem, że jest wywołana od członka "A". Zaktualizowałem odpowiedź. Dzięki. –

0

Tylko is_odd statyczne, więc nie będzie wymagać niejawny this parametr:

static bool is_odd(int i) 

nie używa żadnych zmiennych składowych lub inne funkcje składowe tak.

Powiązane problemy