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?

Author: 0xbadf00d, 2011-01-28

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.

 11
Author: Matthieu M.,
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; 
 5
Author: Nikos Athanasiou,
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 ;
  }
 2
Author: TonyK,
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.

 1
Author: Mark B,
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...

 -3
Author: googling,
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