Czy typ zwracany jest częścią podpisu funkcji?

W C++, czy zwracany typ jest uważany za część sygnatury funkcji? i żadne przeciążenie nie jest dozwolone, tylko zmodyfikowany Typ powrotu.

Author: yesraaj, 2008-11-14

3 answers

Normalne funkcje nie zawierają typu return w swojej sygnaturze.

(Uwaga: przepisałem tę odpowiedź, a poniższe komentarze nie odnoszą się do tej zmiany - zobacz szczegóły w historii edycji).

Wprowadzenie

Jednak sprawa funkcji i deklaracji funkcji w standardzie jest skomplikowana. Istnieją dwie warstwy, które należy wziąć pod uwagę:

  • deklaracje
  • byty

The tak zwana deklaracja funkcji może zadeklarować jednostkę funkcji lub jednostkę szablonu. Jeśli encja funkcji jest zadeklarowana, to albo masz do czynienia z wyraźną specjalizacją szablonu funkcji (z podanymi wszystkimi argumentami), albo z deklaracją zwykłej funkcji. Jeśli encja szablonu jest zadeklarowana, to deklarujesz podstawowy szablon funkcji lub jawną specjalizację, w której niektóre argumenty nie są określone. (Jest to bardzo podobne do relacji " obiekt declaration " i Obiekty lub odniesienia: pierwsze z nich może zadeklarować obiekt lub odniesienie. Tak więc deklaracja obiektu niekoniecznie może zadeklarować obiekt!).

Standard definiuje sygnaturę funkcji tak, aby zawierała następujące elementy w 1.3.10:

Typy jej parametrów i, jeśli funkcja jest członkiem klasy, kwalifikatory cv (jeśli istnieją) na samej funkcji i klasie, w której funkcja jest zadeklarowana. Podpis funkcji specjalizacja szablonu obejmuje rodzaje argumentów szablonu. (14.5.5.1)

W tej definicji brakuje typu zwrotnego, który jest częścią podpisu specjalizacji szablonu funkcji (tj. deklaracji funkcji, która deklaruje funkcję, która jest specjalizacją szablonu), jak wskazano w 14.5.5.1 (ostatnie dokumenty robocze C++0x naprawiły to już wspominając o typie zwrotu w 1.3.10):

Podpis szablonu funkcji specjalizacja składa się z podpisu szablonu funkcji i rzeczywistych argumentów szablonu (bez względu na to, czy jest wyraźnie określony, czy wydedukowany).

Podpis szablonu funkcji składa się z jego podpisu funkcji, typu zwracanego oraz listy parametrów szablonu.

Co dokładnie zawiera podpis?

Zatem, gdy pytamy o sygnaturę funkcji , musimy dać dwie odpowiedzi:

  • dla funkcji, które są specjalizacjami szablonów funkcji, podpis zawiera typ powrotu.
  • dla funkcji, które nie są specjalizacjami, typ zwracany nie jest częścią sygnatury.

Zauważ jednak, że typ zwracany w każdym przypadku jest znaczącą częścią typu funkcji. Oznacza to, że nie obowiązuje:

void f();
int (*pf)() = &f; // different types!

Kiedy przeciążenie jest nieważne, jeśli różni się tylko Typ powrotu?

Główne Kompilatory obecnie odrzucają następujące kod:

int f();
double f(); // invalid

Ale Zaakceptuj następujący kod:

template<typename T> int f();
template<typename T> double f(); // invalid?

Standard zabraniaĺ ' jednak deklaracji funkcji, ktĂłra róşni siÄ ™ tylko typem zwracanym (gdy definiujemy, kiedy przeciÄ ... Ĺźenie jest waĹźne, a kiedy nie). Nie definiuje jednak dokładnie, co oznacza "różni się tylko typem return".


Odniesienia do akapitu standardowego:

  • kiedy deklaracja funkcji może być przeciążona: 13.1
  • Co to jest deklaracja funkcji: 7/2 i 7/5
  • jaki jest podpis szablonu funkcji / specjalizacji: 14.5.5.1
[11]}dla odniesienia, oto co najnowszy projekt C++0x N3000 mówi o "podpisie" w 1.3.11, który jest znacznie bardziej kompletny w swoim pokryciu różnych typów jednostek:

Nazwa i lista typów parametrów (8.3.5) funkcji, a także klasa lub Przestrzeń nazw, której jest członkiem. Jeśli funkcja lub szablon funkcji jest członkiem klasy, jego podpis dodatkowo zawiera kwalifikatory cv (jeśli istnieją) i kwalifikator ref (jeśli istnieją) w samej funkcji lub szablonie funkcji. Podpis szablonu funkcji zawiera dodatkowo jego typ powrotu i listę parametrów szablonu. Sygnatura specjalizacji szablonu funkcji obejmuje podpis szablonu, którego jest specjalizacją, oraz jego argumenty szablonu (bez względu na to, czy jest wyraźnie określony, czy wydedukowany). [Uwaga: podpisy są używane jako podstawa do manipulowania nazwami i łączenia. - end Uwaga]

 79
Author: Johannes Schaub - litb,
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
2009-12-18 12:09:20

Zależy czy funkcja jest szablonem funkcji czy nie.

W C++ Templates -- The complete guides , Jusuttis podaje inną definicję podaną w standardzie C++, ale z równoważnymi konsekwencjami:

Definiujemy sygnaturę funkcji jako następującą informację:

  1. nazwa niewykwalifikowana funkcji
  2. klasa lub przestrzeń nazw Zakres tej nazwy, a jeśli nazwa ma w języku polskim nazwa ta jest używana w języku polskim.]}
  3. The const, volatile, lub const volatile kwalifikacja funkcji
  4. typy parametrów funkcji
  5. zwraca typ , Jeśli funkcja jest generowana z szablonu funkcji
  6. parametry szablonu i argumenty szablonu , Jeśli funkcja jest generowana z szablonu funkcji

Jak zasugerował litb , to warto wyjaśnić, dlaczego Typ return jest częścią podpisu funkcji szablonu.

Funkcje mogą współistnieć w programie, jeśli mają wyraźne podpisy.

. To powiedziawszy, jeśli typ zwracany jest parametrem szablonu:

template <typename T>
T foo(int a)
{return T();}

Możliwe jest utworzenie dwóch funkcji, które różnią się tylko typem zwracanym:

foo<int>(0);
foo<char>(0);

Nie tylko: jak słusznie donosi litb, możliwe jest również Przeciążenie dwóch funkcji szablonu, które różnią się tylko typ zwracany, nawet jeśli typ zwracany nie jest nazwą zależną. Oto jego przykład:

template<class T> int foo(T)
{}

template<class T> bool foo(T)
{}

// at the instantiation point it is necessary to specify the cast
// in order not to face ambiguous overload

((int(*)(char))foo<char>)('a'); 
 10
Author: Nicola Bonelli,
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
2008-11-15 12:14:34

Są one wystarczającą częścią typu, że można przeciążać funkcje oparte na typach wskaźników funkcji, które różnią się tylko typem zwracanym:

int IntFunc() { return 0; }
char CharFunc() { return 0; }

void FuncFunc(int(*func)()) { cout << "int\n"; }
void FuncFunc(char(*func)()) { cout << "char\n"; }


int main()
{
    FuncFunc(&IntFunc); // calls void FuncFunc(int_func func)
    FuncFunc(&CharFunc); // calls void FuncFunc(char_func func)
}
 2
Author: Eclipse,
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
2008-11-21 18:11:50