Newsgroup: it.comp.lang.c++
Titolo: Funzione che stampi la riga del sorgente dove e` chiamata...

Ciao a tutti,
vorrei porvi un problema che proprio non riesco a risolvere....
Io ho bisogno di fare una funzione che stampi la riga del codice in cui e`
stata chiamata:
per es.
 1:    void fun( int iRow )
 2:    {
 3:         printf( "Row: %d\n", iRow );
 4:         ....
 5:    }
 6:    #define FUN() fun( __LINE__ )
 7:
 8:
 9:    int main( )
10:    {
11:        ....
12:        FUN();
13:        return 0;
14:    }
Dovrebbe stampare 12...
e se F() venisse chiamata da un altra funzione dovrebbe funzionare bene
comunque:
112:    int altraFunzione( )
113:    {
114:        ...
130:        FUN();
131:        ...
150:    }
dovrebbe stampare 130
Ora il mio problema viene fuori quando la funzione vuole dei parametri! Se
questi sono di numero determinati il problema non sussiste:
1:    void fun( int iRow, char *pcStr, int iNum )
2:    {
3:         printf( "Row: %d\n", iRow );
4:         ....
5:    }
6:    #define FUN( s, i ) fun( __LINE__, s, i )
Come faccio, invece se il numero dei parametri e` variabile:
void fun( int iRow, char *pcStr, ... )
Aiuto!! :(

 Aiuto!! :(
se non ricordo male, le macro devono avere un numero prefissato di 
parametri, quindi quello che chiedi tu mi sa che non si possa fare tanto 
semplicemente. Perň, potresti fare in modo che la macro restituisca un 
oggetto proxy che ridefinisce l'operatore ()...
-- 
There are better things in life than alcohol, but alcohol makes up for 
not having them. - Terry Pratchett.

 oggetto proxy che ridefinisce l'operatore ()...
?!?
Mi sa di non aver capito :(

Zio wrote:

pensavo ad una cosa del genere:
#include <string>
#include <iostream>
class Proxy	{
public:
	explicit Proxy(int line): _line(line)
	{}
	Proxy & operator * () const	{
		std::cout<< "line "<< _line<< ": "<< _text<< std::endl;
	}
	Proxy & operator () (const std::string & text)	{
		_text.append(text);
		return *this;
	}
private:
	std::string _text;
	int _line;
};
Proxy buildFun(int line)	{ return Proxy(line);}
#define FUN()   *buildFun(__LINE__)
int main()	{
	FUN()("Ciccio palla bum bum!")(" ...")(" quanti ne vuoi.");


 void fun( int iRow, char *pcStr, ... )
#define FUN( s, i, ...) fun( __LINE__, s, i, __VA_ARGS__)
Non so se è standard; vedi il tuo compilatore.
Attenzione: mi sembra che poi non puoi mettere non-parametri, cioè
chiamare FUN(s,i) sarà un errore. Verifica.
Saluti
-- 
alef

Io ti ringrazio tanto per la possibile soluzione che mi hai mandato, ma non
sono stato a spiegare tutto (perche` gia` mi ero dilungato troppo) ma mi
servirebbe una funzione o qualcosa che sembri tale...
Ad es come la soluzione di "alef" che pero` non mi va bene perche` non e`
standard e comunque non riesco nemmeno a compilarla...
Grazie.

 standard e comunque non riesco nemmeno a compilarla...
probabilmente "non riesci a compilarla" č l'effetto, che "non č 
standard" č la causa. Che compilatore usi?


 chiamare FUN(s,i) sarà un errore. Verifica.
Grazie.
In effetti avrei bisogno di una soluzione standard, e inoltre non e`
compilabile con VC :(

 Che compilatore usi?
VC++

Zio wrote:

l'ultima idea, una modifica sulla precedente:
#include <cstdarg>
#include <string>
#include <iostream>
class Proxy	{
public:
	explicit Proxy(int line): _line(line)
	{}
	Proxy & operator * () const	{
		std::cout<< "line "<< _line<< ": "<< _text<< std::endl;
	}
	Proxy & operator () (const char * text, ...)	{
         char buffer[0x100];
         va_list ap;
         va_start(ap, text);
         vsprintf(buffer, text, ap);
         va_end(ap);
		_text.assign(buffer);
		return *this;
	}
private:
	std::string _text;
	int _line;
};
Proxy buildFun(int line)	{ return Proxy(line);}
#define FUN *buildFun(__LINE__)
int main()	{
	FUN("Ciao, %s!", "mondo");
}
meglio di cosě non posso fare.



MA BELLA!!!
ci faccio solo una modifichina qui e basta:
Proxy & operator () (const char * text, ...)
{
    char buffer[ 0x100 ];
    vsprintf( buffer, text, (va_list) ( &text + 1 ) );
    _text.assign( buffer );
    return *this;
}
GRAZIE!