Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[boost] ciclo statico su una tupla

0 views
Skip to first unread message

Marco De Paoli

unread,
Jul 18, 2008, 6:25:09 AM7/18/08
to
ciao a tutti,
vorrei fare un ciclo statico su una tupla di n interi

dato che boost::tuple non prevede cicli, penso che il modo più
semplice sarebbe scomodare boost::fusion

il problema è che fusion è nella 1.35 di boost e noi, per altri
motivi, siamo al momento fermi alla 1.34.1

qualche altra idea?
thanks in advance

ciao,
Marco

Max M.

unread,
Jul 18, 2008, 2:40:38 PM7/18/08
to
Marco De Paoli wrote:
> ciao a tutti,
> vorrei fare un ciclo statico su una tupla di n interi

Non conosco benissimo boost::tuple, ma con poche righe di codice (che metto
in fondo al messaggio) ho creato una funzione template 'for_each', che ti
permette di invocare un oggetto funzione su ogni elemento della tupla.


struct print
{
template< class T >
void operator()( const T& v )
{ cout << v << endl;
}
};

int main()
{
tuple<int,char,std::string> t;

t.get<0>() = 1;
t.get<1>() = 'C';
t.get<2>() = "foo";

for_each( t, print() );
}


Ovviamente si possono fare cose pi� sofisticate, e pi� eleganti, come quelle
che fa fusion. Ma se ti basta questo, il codice � sotto la firma.

Max

#include "boost/tuple/tuple.hpp"


template< int Num, class Tuple, class Pred >
struct
for_each_impl
{
for_each_impl( const Tuple& t, Pred op )
{ using namespace boost;
// non ho capito perch�, ma senza questo using non compila
for_each_impl<Num-1,Tuple,Pred> prev(t,op);
op( t.get<Num>() );
}
};

template< class Tuple, class Pred >
struct
for_each_impl<0,Tuple,Pred>
{
for_each_impl( const Tuple& t, Pred op )
{ using namespace boost;
op( t.get<0>() );
}
};

template< class Tuple, class Pred >
void
for_each( const Tuple& t, Pred op )
{
for_each_impl< tuples::length<Tuple>::value-1,Tuple,Pred> impl(t,op);
};

>
> dato che boost::tuple non prevede cicli, penso che il modo pi�


> semplice sarebbe scomodare boost::fusion
>

> il problema � che fusion � nella 1.35 di boost e noi, per altri

Marco De Paoli

unread,
Jul 21, 2008, 6:23:39 AM7/21/08
to
On 18 Lug, 20:40, "Max M." <ed...@maxim.comm2000.it> wrote:

> Non conosco benissimo boost::tuple, ma con poche righe di codice (che metto
> in fondo al messaggio) ho creato una funzione template 'for_each', che ti
> permette di invocare un oggetto funzione su ogni elemento della tupla.

pensavo a qualcosa di già pronto (magari in qualche parte di boost che
non conoscevo)
Max, me lo hai addirittura implementato :-)

grazie,
Marco

P.S. per la cronaca sul VC2500 non serve
using namespace boost;

Max M.

unread,
Jul 21, 2008, 8:40:56 AM7/21/08
to
Marco De Paoli wrote:
>
> P.S. per la cronaca sul VC2500 non serve
> using namespace boost;

Visto che anche uno dei GCC più recenti (4.1.3) non compila quel codice
senza aggiungere lo 'using', mi piacerebbe capire quale dovrebbe essere il
comportamento del compilatore a norma di standard.

Se riscrivo la parte incriminata come

op( t.template get<0>() ); /* aggiungendo 'template' */

anche il GCC lo compila senza 'using'.

Mi pare che in questi casi la keyword "template" sia in effetti
obbligatoria, essendo 'get' un "dependent name".

Il fatto che GCC lo compili con lo 'using' semprerebbe, perciò, accidentale.

Max

Marco De Paoli

unread,
Jul 21, 2008, 9:49:08 AM7/21/08
to

ho dato un occhiata agli header di tuple: get è un metodo di un
ancestor di tuple
di conseguenza non dovrebbe neanche servire scomodare il Koenig lookup
per rintracciarlo:
è semplicmente un metodo ereditato dalla classe

sinceramente non capisco perchè sia necessaria la keyword
"template" (o in alternativa lo "using")

Marco

Max M.

unread,
Jul 21, 2008, 10:56:09 AM7/21/08
to
Marco De Paoli wrote:
> ho dato un occhiata agli header di tuple: get è un metodo di un
> ancestor di tuple di conseguenza non dovrebbe neanche servire
> scomodare il Koenig lookup per rintracciarlo: è semplicmente un
> metodo ereditato dalla classe

Sì, però, poiché la mia classe è templatizzata proprio sul tipo a cui viene
applicato 'get', quel nome è un "dependent name". Questo dettaglio è
essenziale.

> sinceramente non capisco perchè sia necessaria la keyword
> "template" (o in alternativa lo "using")

La keyword 'template' è necessaria perché lo Standard richiede che il
compilatore abbia informazioni sufficienti per disanbiguare sintatticamente
l'espressione in questione prima dell'effettiva instanziazione. Sapere che
un "dependent name" si riferisce a un template, consente di decidere come
interpretare il segni '<' e '>', che altrimenti genererebbero ambiguità.
Basta considerare questo codice

t.get<0>(arg) ;

e immaginare di instanziarlo per un tipo che abbia un membro 'get', a cui
sia possibile applicare l'operatore '<'.

Gli estensori dello Standard hanno deciso che certe ambiguità devono essere
risolte nella primissima fase di compilazione di un template.

Alcuni compilatori, evidentemente, posticipano tutte le decisioni al momento
in cui il template viene istanziato. Questo non è conforme allo Standard, e
può portare a istanziazioni che non dovrebbero essere consentite.

Non so perché, invece, GCC compili quel codice se si aggiunge lo 'using'.
Non trovo ragioni valide, e -come ho detto- tendo a credere che sia un
fatto accidentale.

Max


Marco De Paoli

unread,
Jul 22, 2008, 5:28:37 AM7/22/08
to
On 21 Lug, 16:56, "Max M." <ed...@maxim.comm2000.it> wrote:
> Sì, però, poiché la mia classe è templatizzata proprio sul tipo a cui viene
> applicato 'get', quel nome è un "dependent name". Questo dettaglio è
> essenziale.

> La keyword 'template' è necessaria perché lo Standard richiede che il


> compilatore abbia informazioni sufficienti per disanbiguare sintatticamente
> l'espressione in questione prima dell'effettiva instanziazione. Sapere che
> un "dependent name" si riferisce a un template, consente di decidere come
> interpretare il segni '<' e '>', che altrimenti genererebbero ambiguità.
> Basta considerare questo codice
>
>      t.get<0>(arg) ;
>
> e immaginare di instanziarlo per un tipo che abbia un membro 'get', a cui
> sia possibile applicare l'operatore '<'.

si, adesso è chiaro

> Gli estensori dello Standard hanno deciso che certe ambiguità devono essere
> risolte nella primissima fase di compilazione di un template.
>
> Alcuni compilatori, evidentemente, posticipano tutte le decisioni al momento
> in cui il template viene istanziato. Questo non è conforme allo Standard, e
> può portare a istanziazioni che non dovrebbero essere consentite.
>
> Non so perché, invece, GCC compili quel codice se si aggiunge lo 'using'.
> Non trovo ragioni valide, e -come ho detto- tendo a credere che sia un
> fatto accidentale.

quello che mi lascia perplesso è che boost::tuple faccia conto su
questo comportamento non standard dei compilatori...

http://www.boost.org/doc/libs/1_35_0/libs/tuple/doc/tuple_users_guide.html#accessing_elements

Marco

Max M.

unread,
Jul 22, 2008, 6:16:38 AM7/22/08
to
Marco De Paoli wrote:
>
> quello che mi lascia perplesso è che boost::tuple faccia conto su
> questo comportamento non standard dei compilatori...
>

Scusami, non capisco il tuo commento. La sintassi senza la keyword
"template" è prefettamente legale, a condizione che l'oggetto sia di un
tipo ben preciso, nel senso che non sia (o non dipenda da) un parametro di
un template. Vale in sostanza lo stesso principio della keyword "typename":
se non si tratta di un "dependent name", non bisogna usarla.

Max


Marco De Paoli

unread,
Jul 22, 2008, 8:17:42 AM7/22/08
to

certo hai ragione
non avevo colto appieno il "dettaglio essenziale"

> Sì, però, poiché la mia classe è templatizzata proprio sul tipo a cui viene
> applicato 'get', quel nome è un "dependent name".

messa così la cosa effettivamente non capisco cosa cambi al
compilatore sapere che siamo nel namespace boost

sono io programmatore nella definizione del template for_each_impl che
devo "chiedere esplicitamente" che il tipo Tuple abbia un template
method di nome "get"

giusto?
ho capito bene il punto oppure continua a sfuggirmi qualcosa?

se ho capito bene non sono comunque in grado di rispondere al tuo
dubbio

perchè dovrebbe essere necessario "using namespace boost"?

in effetti boost::tuple è il tipo effettivo su cui viene istanziato il
template
il fatto che per il gcc l'uso della direttiva "using namespace boost"
faccia differenza sembra confermare la tua ipotesi:
il compilatore attende una fase successiva, nella quale ha maggiori
informazioni, per mappare l'identificatore "get" sul metodo
"tuple::get"
a quel punto è ovviamente anche in grado di dedurre che "get" è un
template method e non un membro o un tipo

ciao,
Marco

Max M.

unread,
Jul 22, 2008, 12:14:49 PM7/22/08
to
Marco De Paoli wrote:
> sono io programmatore nella definizione del template for_each_impl che
> devo "chiedere esplicitamente" che il tipo Tuple abbia un template
> method di nome "get"
>
> giusto?
> ho capito bene il punto oppure continua a sfuggirmi qualcosa?

Giusto. (Sempre che io non stia prendendo una cantonata; ogni tanto mi
càpita.)

>
> perchè dovrebbe essere necessario "using namespace boost"?
>

Infatti, secondo me è un effetto accidentale di qualche dettaglio
implementativo del GCC.

Con o senza 'using', il codice non è legale se non si aggiunge 'template'.
Perciò entrambi i compilatori -VC2005 e GCC4- non rispettano lo standard
in questo aspetto. (Credo.)

Max

0 new messages