[C++] Problema funzione(parametro x, int (puntatore a funzione*)())

di il
11 risposte

[C++] Problema funzione(parametro x, int (puntatore a funzione*)())

Salve a tutti ragazzi.
Vorrei delle delucidazioni in merito alla fattibilità o meno di questo problema. Per poter rispondere a delle richieste di vario genere su una struttura, ho pensato di inserire tra i parametri di un metodo che ne effettua la visita un puntatore ad una funzione di supporto. Mi spiego meglio, ad esempio per la struttura dati ad Albero ho pensato ad una funzione di questo tipo :

void preorder_traversal( TreeNode<T> * root, void (fn*) ( ...) );

/*ad esempio usata  per stampare */
	preorder_traversal( n1, print);
	
Fin qui tutto bene, a patto che il puntatore a funzione passato come parametro sia di tipo void o bool. Quello che mi chiedo è se in qualche modo io possa ottenere più informazioni sfruttando quel puntatore a funzione, quali un semplice intero , un vettore d'interi, meglio ancora se un tipo di struttura dati. Faccio un esempio per spiegarmi meglio.. è possibile al livello implementativo sfruttare tale metodo in combinazione con una funzione che non so, calcoli il numero di elementi presenti? Oppure è meglio trovare una soluzione alternativa?

 
void preorder_traversal( TreeNode<T> * root, int (fn*) ( ...) );

template <class T>
int counter(TreeNode<T>*);

11 Risposte

  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Se vuoi estrarre dati da un puntatore a funzione, sei costretto a usare variabili globali.
    L'alternativa è usare un function object ( una classe o struttura che usa operator() ) che può (se passato per reference) di estrarre dati eventuali da elaborare dopo la chiamata del metodo a cui è passato.
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Un function object può essere come il seguente ?
    
    
    template<class T>
    class is_even
    {
    public:
    	is_even() {};
    	bool operator() (T val){ return (abs(val) % 2 == 0); }
    	
    };
    
    
    Grazie mille per il prezioso aiuto.
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Si, ovviamente tipo di ritorno e parametro d'ingresso devono essere quelli che hai stabilito nella funzione in cui è usato il function object
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Per le strutture dati lineari è stato facile, nessun problema.... la disgrazia mi si presenta sempre sulle strutture ad albero forse perchè ho sbagliato qualcosa in fase di progettazione, non riesco a venirne a capo! Questa qui è la bozza della mia classe Albero N- Ario
    
    
    template <class Element>
    class Nary_Tree
    {
    public:
    	Nary_Tree();
    	Nary_Tree(const Element root);
    	Nary_Tree(size_t nodes, size_t start_range, size_t end_range);
    	Nary_Tree(Tree_Node<Element>* root);
    	Nary_Tree(const Nary_Tree<Element>& to_copy);  
    
    	~Nary_Tree();
    
    	Tree_Node<Element>* get_root();
    	size_t get_height();
    	size_t get_size();
    	
    	Nary_Tree<Element>& get_first_sub_tree();
    	Nary_Tree<Element>& get_sub_tree(size_t pos);
    	
    
    	void set_root(Element new_root);
    	void set_first_sub_tree(const Element first);
    	void set_sub_tree(const Element child);
    	
    	
    
    	//utility
    	bool is_empty();
    	void refresh();
    	void remove_sub_tree(Nary_Tree<Element>& sub_tree);
    	
    	
    	//visit
    	void pre_order(Tree_Node<Element>* node, void(*fn)(Tree_Node<Element>*));
    	void post_order(Tree_Node<Element>* node , void(*fn)(Tree_Node<Element>*));
    	void breadth_first_order();
    	List<Element>* breadth_first(Tree_Node<Element>* node); //optional...
    
    	/* overload ... */
    
    private:
    	Tree_Node<Element> * root_;
    	size_t height_;
    	size_t size_;
    }
    
    Questa invece è una bozza di una funzione il cui compito è quello di contare le occorrenze del verificarsi di una condizione passata come parametro ( Predicate è il segnaposto per un function object,almeno spero di averlo implementato nella maniera migliore )
    
    // the idea is to count occurrences in which the condition is true
    template<class Tree, class Predicate>
    int count_if(Tree nary_tree , Predicate condition)
    {
    	int counter = 0;	
    	nary_tree.post_order(nary_tree.get_root(), //Help);
    	
    	...
    	...
    	...
    	
    	return counter;
    }
    
    Ora assumendo che l' approccio sia giusto(non ne ho la certezza, poichè è la mia prima esperienza sul paradigma object oriented)il problema che mi si presenta è che formalmente non ho idea di come riscrivere l argomento dei prototipi dei metodi di visita [ mi riferisco ad esempio al pre_order(Tree_Node<Element>*,void (fn*)(questa roba qui)]... Secondo voi è possibile procedere in questo modo ? o conviene trovare un altra soluzione del tutto differente? Vi prego aiutatemi
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    il segnaposto per un function object,almeno spero di averlo implementato nella maniera migliore
    Proprio no. Hai solo dichiarato un puntatore a funzione. Un function object resta comunque un oggetto, per cui:
    
    void pre_order(Tree_Node<Element>* node, MyPred condition );
    
    dove MyPred sarà qualcosa del genere (di norma con Predicato si intende un f.o. che restituisce un boolean) :
    
    struct MyPred { // o class 
        int& cnt;
        MyPred(int c) : cnt(c) {}
    
        template <typename Elem>
        bool operator()(TreeNode<Elem>* elem) {
            counter++;
            // qualcosa che restituisca true o false a seconda dei casi
        }
    };
    ...
    void pre_order(Tree_Node<Element>* node, MyPred condition ) {
        condition(node);
    }
    ...
    nary_tree.post_order(nary_tree.get_root(), MyPred(counter) );
    
    Solo che non ho ancora capito se devi tirare fuori dei dati.
    In alternativa si potrebbe scrivere:
    
    void pre_order(Tree_Node<Element>* node, std::function<bool(Tree_Node<Element>*)> condition);
    ...
    void pre_order(Tree_Node<Element>* node, std::function<bool(Tree_Node<Element>*)> condition ) {
        condition(node);
    }
    
    nary_tree.post_order(nary_tree.get_root(), [&counter]( Tree_Node<Element>* elem) ->bool {
        counter++;    
        // qualcosa che restituisca true o false a seconda dei casi
    });
    
    Personalmente opterei per la seconda soluzione, in grado di accettare anche puntatori a funzione e non solo lambda o function object.
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    shodan ha scritto:


    
    void pre_order(Tree_Node<Element>* node, MyPred condition );
    
    A volte mi perdo in un biccher d 'acqua...grazie mille...
    Solo che non ho ancora capito se devi tirare fuori dei dati.
    Si, dovrei insomma estrarre il contatore in questo caso...ossia nel main dovrei avere una cosa del genere
    
    
    int main()
    {
    
    	Nary_Tree<int> my_tree(... ... ...);
    	
    	...
    	...
    	//ad esempio usare un  predicato tipo is_even
    	
    	int even_nodes = 0;
    	is_even<int> even;
    	
    	even_nodes = count_if(my_tree,even); 
    	...
    	
    }
    
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Quindi tornando all' esempio dell' uso della funzione count_if per contare le foglie di un albero n ario, un function object del genere può andar bene?
    
    template<class Node>
    class is_leaf
    {
    public:
    	is_leaf() { leaves = 0; };
    	bool operator() (Node& node) 
    	{
    		bool answer = false;
    
    		if (node->is_leaf())
    		{
    			leaves++;
    			answer = true;
    		}
    		
    		return answer;
    	}
    	
    	int get() { return leaves;};
    	
    private:
    	int leaves;
    
    };
    
    

    usato in questo modo?
    
    
    int count_if(Tree nary_tree , MyPred conditionn)
    {
       int counter = 0;   
       nary_tree.post_order(nary_tree.get_root(), condition);
       
       counter = condition.get();
       return counter;
    }
    
    
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Si, a patto che tu sappia a priori il tipo Node con cui dare l'istanza. Ovviamente count_if dovrà avere la dichiarazione del template per i tipi usati.
    P.S.
    esiste una std::count_if negli header standard. Occhio a non andarci in conflitto.
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Grazie mille per le preziose dritte.. un ultima cosa, esiste un modo per aggiungere un parametro template in più solo per alcuni metodi della classe ? (In questo caso mi.riferisco ovviamente ai soli metodi di visita, in cui mi farebbe comodo avere ad esempio Mypred come template) Oppure sono costretto ad aggiungerlo sopra nella dichiarazione della classe ? E se cosi fosse, nell istanziarne gli oggetti, potrei specificarne solo uno dei due (quello che ne rappresenti il tipo di etichetta dei nodi)?
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    Si. E non possono essere virtual (nel caso lo chiedessi in seguito).
    
    template <class Element>
    class Nary_Tree
    {
        public:
        ...
       template <typename MyPred>
       void pre_order(Tree_Node<Element>* node, MyPred pred);
    
    se la sviluppi fuori dal corpo della classe:
    
    template <typename Element>
    template <typename MyPred>
    inline void Nary_Tree<Element>::pre_order(Tree_Node<Element>* node, MyPred pred) {
    ...
    }
    
  • Re: [C++] Problema funzione(parametro x, int (puntatore a funzione*)())

    MI HAI SALVATO! GRAZIE INFINITE
Devi accedere o registrarti per scrivere nel forum
11 risposte