Prosíme přihlašte se nebo zaregistrujte.

Přihlašte se svým uživatelským jménem a heslem.
Vaše pomoc je stále potřeba!

Autor Téma: C++ odkaz na funkci  (Přečteno 1710 krát)

Kedrigern

C++ odkaz na funkci
« kdy: 28 Března 2012, 01:09:19 »
Ahoj, mám přibližně takovýto kód:
Kód: [Vybrat]
#include <iostream>
#include <algorithm>
#include <vector>
#include <utility>

typedef std::pair<std::size_t, std::size_t> point;

void print( point i) {
        std::cout << i.first << ", ";
}

class A {
public:
        A( std::vector< point >& v) {
                std::for_each(v.begin(), v.end(), ::print );
                std::cout << std::endl;
                //std::for_each(v.begin(), v.end(), this->print2 );
                std::cout << std::endl;
        }

        void print2 ( point i ) {
                std::cout << i.first << ", ";
        }
};

int main(void) {
        std::vector< point > vec;
        vec.push_back( point(3,3) );
        vec.push_back( point(4,4) );

        A a( vec );     
        return 0;
}
Což normálně zkompiluji:
Kód: [Vybrat]
g++ -std=c++0x -Wall -pedantic test.cpp
clang++ test.cpp

Když odkomentuji řádek 17, tak již nezkompiluji. Nicméně já bych v tom for_each právě potřeboval volat členskou funkci dané třídy.

Chybový výpis g++:
Kód: [Vybrat]
test.cpp: In constructor ‘A::A(std::vector<std::pair<long unsigned int, long unsigned int> >&)’:
test.cpp:17:50: error: argument of type ‘void (A::)(point) {aka void (A::)(std::pair<long unsigned int, long unsigned int>)}’ does not match ‘void (A::*)(std::pair<long unsigned int, long unsigned int>)’
In file included from /usr/include/c++/4.6/algorithm:63:0,
                 from test.cpp:2:
/usr/include/c++/4.6/bits/stl_algo.h: In function ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<std::pair<long unsigned int, long unsigned int>*, std::vector<std::pair<long unsigned int, long unsigned int> > >, _Funct = void (A::*)(std::pair<long unsigned int, long unsigned int>)]’:
test.cpp:17:50:   instantiated from here
/usr/include/c++/4.6/bits/stl_algo.h:4302:2: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘__f (...)’, e.g. ‘(... ->* __f) (...)’

Chybový výpis clang++:
Kód: [Vybrat]
test.cpp:17:3: error: no matching function for call to 'for_each'
                std::for_each(v.begin(), v.end(), this->print2 );
                ^~~~~~~~~~~~~
In file included from test.cpp:2:
In file included from /usr/include/c++/4.6/algorithm:62:
/usr/include/c++/4.6/bits/stl_algo.h:4296:5: note: candidate function [with _InputIterator =
      __gnu_cxx::__normal_iterator<std::pair<unsigned long, unsigned long> *, std::vector<std::pair<unsigned
      long, unsigned long>, std::allocator<std::pair<unsigned long, unsigned long> > > >, _Function = void
      (*)(std::pair<unsigned long, unsigned long>)] not viable: no known conversion from 'void (point)' to 'void
      (*)(std::pair<unsigned long, unsigned long>)' for 3rd argument
    for_each(_InputIterator __first, _InputIterator __last, _Function __f)
    ^
1 error generated.
« Poslední změna: 28 Března 2012, 11:17:36 od Kedrigern »

Martin - ViPEr*CZ*

Re:C++ odkaz na funkci
« Odpověď #1 kdy: 28 Března 2012, 10:09:13 »
Tu funkci budeš muset volat staticky... tedy ne přes this, ale identifikátorem rozlišení ze které je classy.
Kód: [Vybrat]
std::for_each(v.begin(), v.end(), A::print2 );Takhle by to mělo fungovat doufám.... neodzkoušeno.
Open source is gold way... Mint 17.2, Debian 8.1 Jessie| Ubuntu Wiki (návody) | Google vyhledávač | Qt4 návody

Kedrigern

Re:C++ odkaz na funkci
« Odpověď #2 kdy: 28 Března 2012, 10:41:58 »
Tu funkci budeš muset volat staticky... tedy ne přes this, ale identifikátorem rozlišení ze které je classy.
Kód: [Vybrat]
std::for_each(v.begin(), v.end(), A::print2 );Takhle by to mělo fungovat doufám.... neodzkoušeno.

Tak to mi bohužel nepomůže, protože v tom reálném kódu je ta funkce nestatická a pracuje s danou třídou. Ale toto funguje, no:
Kód: [Vybrat]
...
std::for_each(v.begin(), v.end(), A::print2 );
...
static void print2 ( point i ) {
...

No udělal jsem to přes nový "foreach" z C++0x (C++11):
Kód: [Vybrat]
for( point &p: v) {
     print2( p );
}
Bohužel je méně přehledný a nefunguje v clangu 2.9. Clang 3 je až v Ubuntu 12.04.

Edit: Tak dobrou zprávou je, že Clang 3 jde zkompilovat ze SVN v Ubuntu 11.10 bez problémů :).
« Poslední změna: 28 Března 2012, 11:18:23 od Kedrigern »

Martin - ViPEr*CZ*

Re:C++ odkaz na funkci
« Odpověď #3 kdy: 28 Března 2012, 14:44:07 »
Pokud ta statická funkce print2 je ve třídě A, pak by jsi měl přistupovat i tak k členským proměnným či chráněným metodám. A nebo si pak namísto for_each udělat vlastní for cyklus.
Open source is gold way... Mint 17.2, Debian 8.1 Jessie| Ubuntu Wiki (návody) | Google vyhledávač | Qt4 návody

 

Provoz zaštiťuje spolek OpenAlt.