Newsgroup: it.comp.lang.c++
Titolo: sintassi per funzione che torna un puntatore ad array

Ciao a tutti.
Approfondendo un po' di sintassi c++ e mi è venuto il dubbio seguente:
data una funzione
int* func1(){
	int* tmp1 = new int[10];
	return tmp1;
}
mi chiedo se si può definire la funzione func2 tale che
X func2(){
	int(*tmp2)[10] = (int(*)[10]) new int[10];  //(*)
	return tmp2;
}
al posto di X cosa ci va?
Sarebbe possibile "templatizzare" func2 in modo da allocare un numero
n arbitrario di int?
Intendo, sostituire la riga (*) con
int(*tmp2)[n] = (int(*)[n]) new int[n];
Grazie

 int(*tmp2)[n] = (int(*)[n]) new int[n];
L'unica soluzione che ho escogitato e' il seguente programma.
E' quello che cercavi?
#include <iostream>
using namespace std;
template <int n>
struct fuct2_aux {
     typedef int (*p_arrN_int)[n];
     static p_arrN_int f() { return (p_arrN_int) new int[n]; }
};
template <int n>
typename fuct2_aux<n>::p_arrN_int func2() {
     return fuct2_aux<n>::f();
}
int main() {
     int (*p)[7] = func2<7>();
     (*p)[4] = 123;
     cout << (*p)[4] << endl;
}
Comunque in pratica e' molto raro l'uso di variabili dinamiche di tipo 
array. I tipi array sono usati quasi esclusivamente per costanti o 
variabili globali.
Gli array dinamici sono normalmente gestiti tramite il puntatore al 
primo elemento, e la loro lunghezza e' determinata solo a run-time, 
cioe' si usa l'espressione "new int[n]" senza eseguire il cast.
-- 
Carlo Milanesi
http://digilander.libero.it/carlmila

Perfetto, grazie 1000.
Se interessa spiego il ragionamento contorto che mi ha condotto fin
qui nel caso qualcuno voglia commentare le mie conclusioni.
Giocherellando con array e puntatori ho scoperto che non è possibile
che una funzione torni un array, cioè non è ammessa una sintassi del
tipo:
    // T = tipo, n = 
n.ro
 elementi, supponiamoli definiti al momento
della compilazione, ad es. 'int' e '10'
    T[n] func(){ ..... };
ci avevo provato anche facendo:
    typedef T T_n[n];
    T_n func(){ .... };
ma chiaramente ottenendo lo stesso risultato.
La soluzione "ufficiale" è quella di tornare un puntatore all'array, o
meglio un puntatore al suo primo elemento:
    T* func(unsigned int n){ return new T[n]; }
da usare così:
    T* pippo = func(n);
    for(int i=0; i<n; i++){}
che secondo me è possibile fonte di problemi se la 'n' nella
definizione e quella del for non coincidono.
Allora mi sono chiesto se fosse possibile ritornare un (vero)
puntatore ad array, cioè del tipo T (*) [n], in modo che chi lo riceve
sia ben con conscio delle sue dimensioni. In questo caso
    T (*pippo) [n] = func(n);
    for(int i=0; i<sizeof(*pippo)/sizeof(*pippo[0]); i++){}
e se le 'n' nella prima riga non coincidono si ha già un errore in
compilazione.
Da qui la mia domanda.
In effetti non avevo pensato a definire il tipo di ritorno di func
'appoggiandomi' ad un typedef, scoraggiato dal precedente tentativo.
La soluzione proposta da Carlo è quella corretta.
    typedef T(*p_T_n) [n];
    p_T_n func(){return (p_T_n) new T[n];}
Infine volevo templatizzare func affinchè la dimensione dell'array
ritornato fosse parametrizzabile ma il compilatore aveva cominciato a
lamentarsi non appena ho provato ad usare un typedef templatizzato.
Anche qui la soluzione di Carlo è stata rivelatrice: mettere il
typedef e func dentro una struct templatizzata
    template<typename T, int n> struct T_arr_N{
      typedef T (*p_T_arr)[n];
      static p_T_arr ptr(){
        //per Carlo: posso manipolare qui l'array da ritornare senza
bisogno
        return (p_T_arr) new T[n];
      }
    };
che posso usare
    int (*pippo) [10] = T_arr_N<int,10>::ptr();
Grazie ancora a Carlo e a chi vorrà lasciare i suoi commenti.
Enzo

scusate, m'è scappato un pezzo nel commento per Carlo
//per Carlo: posso manipolare qui l'array da ritornare senza bisogno
di func2