2013-07-03 21 views
11

Mam problem ze zrozumieniem typy funkcyjne (pojawiają się one na przykład jako parametr Signature szablonu z std::function):C++ typy funkcyjne

typedef int Signature(int); // the signature in question 

typedef std::function<int(int)> std_fun_1; 
typedef std::function<Signature> std_fun_2; 

static_assert(std::is_same<std_fun_1, std_fun_2>::value, 
       "They are the same, cool."); 

int square(int x) { return x*x; } 

Signature* pf = square; // pf is a function pointer, easy 
Signature f;    // but what the hell is this? 
f(42);     // this compiles but doesn't link 

Zmienna f nie można przypisać, ale można nazwać. Dziwne. Po co więc jest to dobre?

Teraz gdybym const zakwalifikować typedef, mogę nadal używać go do budowania kolejnych rodzajów ale widocznie do niczego innego:

typedef int ConstSig(int) const; 

typedef std::function<int(int) const> std_fun_3; 
typedef std::function<ConstSig>  std_fun_4; 

static_assert(std::is_same<std_fun_3, std_fun_4>::value, 
       "Also the same, ok."); 

ConstSig* pfc = square; // "Pointer to function type cannot have const qualifier" 
ConstSig fc;   // "Non-member function cannot have const qualifier" 

Co odległy zakątek języku ja tu trafić? W jaki sposób wywoływany jest ten dziwny typ i jak mogę go użyć poza parametrami szablonu?

+0

Standardowo po prostu pozwala zadeklarować * * funkcje przez typedef do ich podpisania (faktycznie, typu funkcja). – Xeo

Odpowiedz

15

Oto odpowiedni akapit ze standardu. To prawie mówi samo za siebie.

8.3.5/10

typedef typu funkcji może być wykorzystywany do deklarowania funkcji, lecz nie mogą być stosowane w celu określenia funkcji (8.4).

przykład:

typedef void F(); 
F fv;   // OK: equivalent to void fv(); 
F fv { }  // ill-formed 
void fv() { } // OK: definition of fv 

typedef typu funkcji którego declarator zawiera CV kwalifikatora SEQ stosuje się jedynie o stwierdzenie, typ function niestatycznych funkcji składowej, na zadeklaruj typ funkcji, do której odnosi się wskaźnik do elementu, lub zadeklaruj typ funkcji najwyższego poziomu innej deklaracji funkcji typedef.

Przykład:

typedef int FIC(int) const; 
FIC f;    // ill-formed: does not declare a member function 
struct S { 
    FIC f;    // OK 
}; 
FIC S::*pm = &S::f; // OK 
+0

Doskonały. To jest dokładnie ta informacja, której szukałem. Dzięki. – marton78

+0

Dzięki! Powinienem był to wcześniej zauważyć. – Bikineev

0

W twoim przypadku std_fun_1 i std_fun_2 są identycznymi obiektami z identycznymi podpisami typu. Oba są std::function<int(int)> i mogą zawierać wskaźniki funkcji lub obiekty wywoływalne typu int(int). Jest to wskaźnik do int(int). Oznacza to, że służy on do tego samego podstawowego celu, co std::function, ale bez mechanizmów tej klasy lub obsługi instancji obiektów wywoływalnych.

Podobnie, std_fun_3 i są identycznymi obiektami z identycznymi sygnaturami typu i mogą zawierać wskaźniki funkcji lub obiekty wywoływalne typu int(int) const.

Również podobnie, pfc jest wskaźnikiem funkcji typu int(int) const i może zawierać wskaźniki dla funkcji tego typu, ale nie instancji obiektów wywoływalnych.

Ale deklaracje funkcji f i fc.

Linia:

Signature fc; 

Czy identycznie równoważne:

int fc(int) const; 

który jest deklaracja dla funkcji o nazwie fc typu int(int) const.

Nie dzieje się tutaj nic dziwnego. Zdarzyło Ci się po składni, którą prawdopodobnie już rozumiesz, z perspektywy, do której nie jesteś przyzwyczajony.