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.
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
):
Co dokładnie zawiera podpis?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.
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
i7/5
- jaki jest podpis szablonu funkcji / specjalizacji:
14.5.5.1
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]
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ę:
- nazwa niewykwalifikowana funkcji
- 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.]}
- The
const
,volatile
, lubconst volatile
kwalifikacja funkcji - typy parametrów funkcji
- zwraca typ , Jeśli funkcja jest generowana z szablonu funkcji
- 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');
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)
}
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