C++ typedef member function Signature syntax
Chcę zadeklarować definicję typu dla sygnatury funkcji członka. Funkcja globalna typedefs wygląda tak:
typedef int (function_signature)(int, int);
typedef int (*function_pointer) (int, int);
Ale nie jestem w stanie tego samego dla funkcji member:
typedef int (foo::memberf_signature)(int, int); // memberf_pointer is not a member of foo
typedef int (foo::*memberf_pointer)(int, int);
Dla mnie brzmi to logicznie, ponieważ "foo::" jest składnią dostępu do członka w klasie foo. Jak wpisać tylko podpis?
5 answers
W przypadku pytań dotyczących niewygodnej składni wskaźnika funkcji, osobiście używam ściągawki: samouczek wskaźników funkcji (do pobrania tutaj , dzięki Vector za wskazanie go).
Podpis funkcji członka jest jednak nieco inny od podpisu funkcji zwykłej, jak się tego doświadczyło.
Jak zapewne wiesz, funkcja member ma ukryty parametr this
, którego Typ należy określić.
typedef int (Foo::*Member)(int, int);
Pozwala określasz, że pierwszym elementem przekazywanym do funkcji będzie Foo*
(a więc twoja metoda naprawdę pobiera 3 argumenty, jeśli o niej pomyślisz, a nie tylko 2.
Jest jednak jeszcze jeden powód, dla którego zmuszamy Cię do podania typu.
Wskaźnik funkcji może odnosić się do funkcji wirtualnej, w takim przypadku sprawy mogą się skomplikować. Dlatego wielkość reprezentacji w pamięci zmienia się w zależności od typu funkcji. Rzeczywiście, Na Visual Studio, a rozmiar wskaźnika funkcji może być od 1 do 4 razy większy od zwykłego wskaźnika. Zależy to w szczególności od tego, czy funkcja jest wirtualna.
Dlatego Klasa, do której odnosi się funkcja jest częścią podpisu i nie ma obejścia.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:18
Można obliczyć klasę docelową w nowoczesnym C++ (post 11), wykorzystując 'typedefing' cechy z aliasów szablonów . To, czego potrzebujesz, wyglądałoby tak:
template<typename T>
using memberf_pointer = int (T::*)(int, int);
Jednak w punkcie deklaracji wskaźnik do funkcji member wykorzystującej tę składnię musiałby określić klasę docelową:
// D is a member function taking (int, int) and returning int
memberf_pointer<foo> mp = &foo::D;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-27 09:36:35
U mnie działa:
#include <iostream>
class foo
{
public:
int g (int x, int y) { return x + y ; }
} ;
typedef int (foo::*memberf_pointer)(int, int);
int main()
{
foo f ;
memberf_pointer mp = &foo::g ;
std::cout << (f.*mp) (5, 8) << std::endl ;
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-28 21:24:40
Powodem, dla którego nie działa z bieżącą składnią jest to, że pierwszeństwo operatora nakazuje, że odnosisz się do funkcji o nazwie foo::memberf_signature
, a nie jakiegokolwiek typu.
Nie wiem na pewno, czy możesz to zrobić, czy nie, ale nie mogłem wymyślić żadnej kombinacji nawiasów, która skłoniła kod do kompilacji z g++ 4.2.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-28 19:57:13
Cóż w zasadzie nie może działać (przynajmniej Nie wiem jak używać g++); Przy użyciu kompilatora borland c++ byłoby słowo kluczowe _ _ closure.
Powodem, dla którego nie kompiluje się jest to, że rozmiar functionpointer (na komputerze x86) zajmuje zawsze >; ale jeśli chcesz wskazać na sygnaturę klasy (interfejsu), rozmiar musi być 64bit: 32 bit dla tego wskaźnika (ponieważ interfejs klasy jest w pamięci tylko raz) i 32 bit dla rzeczywistej funkcji
Ale _ _ zamknięcie słowo kluczowe jest językiem BCB "hack" nie znormalizowanym...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-28 20:08:17