Strona 1 z 1

C++ - Zasłanianie nazw - ambiguates old declaration ??

: 21 sty 2012, 19:10
autor: teka321
Czy podany program powinien zadziałać czy powinien generować błędy jak to robi?

#include <iostream>
using namespace std;

float takasama(int tab, float ile);
int takasama(int tab, float ile);

int main()
{

int c;
float p;
p=takasama(5,6);
c=takasama(5,6);

cout << "Wyśwoietli float" <<" " << p << endl;
cout << "Wyśwoietli int" <<" " << c << endl;

return 0;
}


float takasama(int tab, float ile)
{
return ile;
}

int takasama(int tab, float ile)
{
return tab;
}

Re: C++ - Zasłanianie nazw - ambiguates old declaration ??

: 21 sty 2012, 21:14
autor: beluosus
Jednoznaczność funkcji jest określana po nazwie i argumentach, a nie po typie zwracanym. Tutaj masz takie same listy argumentów, więc będzie błąd.

Re: C++ - Zasłanianie nazw - ambiguates old declaration ??

: 21 sty 2012, 21:23
autor: teka321
Ok, dzięki za konkretną odpowiedz. Myślałem że kompilator domyśli się jaką funkcje ma wywołać po tym do jakiego typu zmiennej ma to zwrócić.

Re: C++ - Zasłanianie nazw - ambiguates old declaration ??

: 26 sty 2012, 19:57
autor: kruchy.jr
Chyba nie ma szans się domyślić, bo można przecież zawołać funkcję bez przypisywania wyniku gdziekolwiek

Re: C++ - Zasłanianie nazw - ambiguates old declaration ??

: 26 sty 2012, 20:02
autor: teka321
Wiem, ale to jest głupota, za wyjątkiem gdy funkcja pracuje na wskaźnikach/referencji i robi coś z wartościami w swoim wnętrzu. A jeśli zwróci wynik to i tak zostanie zapisany nie wiadomo gdzie.. no to po co takie wywołanie, oprócz powodów które wcześniej wymieniłem?

Re: C++ - Zasłanianie nazw - ambiguates old declaration ??

: 26 sty 2012, 20:41
autor: norvoles
Ja bym problem rozwiązał tak:

Kod: Zaznacz cały

#include <iostream>
using namespace std;

class Example{
	private:
		int a;
		double b;

	public:
		Example & function (int arg1, double arg2){
			this->a = arg1;
			this->b = arg2;
			return * this;
		}

		operator int() { return a; }
		operator double() { return b; }
};

int main()
{
	Example ex;

	int a =  ex.function(6,8.2);
	double b = ex.function(6,8.2);

	cout << a << "\t" << b << endl;

	return 0;
}
Zwraca co trzeba, zależnie od sytuacji.
A na zadanie domowe możesz pomyśleć jak to działa ;)

Re: C++ - Zasłanianie nazw - ambiguates old declaration ??

: 26 sty 2012, 21:44
autor: beluosus
Dajmy na to, że masz funkcję pow:

Kod: Zaznacz cały

     double pow (      double base,      double exponent );
long double pow ( long double base, long double exponent );
      float pow (       float base,       float exponent );
     double pow (      double base,         int exponent );
long double pow ( long double base,         int exponent );
I teraz masz kod:

Kod: Zaznacz cały

int i = pow(10, 3);
W tym momencie każda funkcja jest odpowiednia - nie ma bardziej odpowiedniej lub mniej odpowiedniej funkcji w tym wypadku (jeśli chodzi o typ zwracany), bo nastąpi niejawne rzutowanie. Kolejny kod:

Kod: Zaznacz cały

#include <cstdio>

void f(float)
{
	printf("float\n");
}

void f(double)
{
	printf("double\n");
}

void f(int)
{
	printf("int\n");
}

void f(char)
{
	printf("char\n");
}
 
int main()
{
	f(65.0f);
	f(65.0);
	f(65);
	f('A');
	
	return 0;
}
Teraz kompilator w trakcie kompilacji ma jakieś informacje co do typu argumentu i może je odpowiednio wykorzystać (zwróć uwagę, że 'A' ma taką samą wartość - 65 - jak pozostałe przykłady). W poprzednim przypadku wartość zwracana jest obliczana w czasie wykonywania programu, więc kompilator nie wie czy zostanie zwrócona wartość 65 (potraktuje jako int), czy 65.5 (potraktuje jako double), czy 65.0 (niby to samo co 65, ale inny zapis binarny ze wzlgędu na typ). Funkcja po prostu zwraca określoną wartość o długości słowa (32 bity dla IA-32 (czy też raczej dwusłowa jak to się przyjęło z x86)). Czy jest to wskaźnik, liczba całkowita czy zmiennoprzecinkowa zależy już tylko od tego jak Twój program ją zinterpretuje. To są metadane, które nie są zapisywane w pliku wykonywalnym - one są tylko dla kompilatora.
Oczywiście można by stosować zapis (lub różnych trików, np takich jak post wyżej, ale moim zdaniem jest to sztuką dla sztuki):

Kod: Zaznacz cały

(long double) pow(10, 3);
static_cast<long double> (pow(10, 3));
Ale najwidoczniej ludzie zajmujący się tworzeniem języka nie uznali tego za dobry pomysł.
teka321 pisze:A jeśli zwróci wynik to i tak zostanie zapisany nie wiadomo gdzie..
Wynik funkcji jest zwracany w rejestrze eax (chyba we wszystkich konwencjach wywoływania funkcji dla x86).