Εμφάνιση 1-5 από 5
  1. #1
    Εγγραφή
    04-02-2009
    Ηλικία
    33
    Μηνύματα
    1.486
    Downloads
    4
    Uploads
    0
    Τύπος
    ADSL
    Ταχύτητα
    2048/256
    ISP
    Cyta Hellas
    Συνέταξα αυτό τον κώδικα σε μια προσπάθεια να αποφύγω (για εκπαιδευτικούς λόγους) την χρήση switch για την κλήση διάφορων συναρτήσεων, με την χρήση function pointers. Τους έχω αποθηκεύσει λοιπόν σε ένα vector:
    Spoiler:
    Κώδικας:
    	
            using fncptr_t = std::function<double( double, double )>;
            std::vector<fncptr_t> vFncPtr{&add, &sub, &mul, &div_};


    Αμέσως μετά (και εδώ θέλω βοήθεια*), αποθηκεύω τους πιθανούς operators σε ένα ακόμη vector, έτσι ώστε να υπάρχει άμεση αντιστοιχία των function pointer με τους operators.
    Spoiler:
    Κώδικας:
    	// Store the operators
    	std::vector<char> vOps{'+', '-', '*', '/'};


    Πιο κάτω συνεχίζω και διαβάζω την είσοδο του χρήστη:
    Spoiler:
    Κώδικας:
    	
            std::cout << "Enter + -> add, - -> sub, * -> mul, / -> div_ " << std::endl;
    	std::cout << "Enter two numbers : ";
    
    	int a, b;
    	char op;
    
    	std::cin >> a >> op >> b;


    Δεν έμειναν πολλά να γίνουν εκτός από το να βρεθεί σε ποια θέση είναι ο οp(erator) για να αντιστοιχηθεί σωστά η συνάρτηση.
    Spoiler:
    Κώδικας:
    	// op is now represents a mathematical operation. I have to extract it's
    	// position in order to call the corresponding function
    	
            std::vector<char>::iterator oper_iterator;
    	oper_iterator = std::find( vOps.begin(), vOps.end(), op );
    	if ( oper_iterator == vOps.end() )
    	{
    		std::cout << "operation " << op << " not supported" << std::endl;
    		return -1;                                                // Exit, no such operation due to invalid input
    	}
    
    	// Find the number that corresponds to op's position in order to call the correct function
    	int oper_pos = std::distance( vOps.begin(), oper_iterator );
    
    	std::cout << "The result of your operation is : \n---\t"
    		  << vFncPtr.at( ( oper_pos ) )( a, b )
    		  << "\t---\nand you executed " << vFnDesc.at( ( oper_pos ) )
    		  << " function." << std::endl;
    	
    	return 0;
    }


    *Ερώτηση 1η: Μπορεί να αντικατασταθεί το vector των operator με έναν απλό enum; Δυστυχώς ο κάτωθι κώδικας είναι λάθος:
    Spoiler:
    Κώδικας:
    	enum class Operator
    	{
    		'+', 
    		'-', 
    		'*', 
    		'/'
                    // Expected identifier error
    	};

    οπότε το std::vector είναι η μόνη μου λύση ως τώρα.

    Ερώτηση 2η: Μπορεί αντί για τόσα vector να χρησιμoποιηθεί το table-driven μοντέλο και να υπάρχουν εντός ενός array/vector οι αντιστοιχίες των operator με τους function pointers απο δίπλα; Έχει κανείς εμπειρία;

    Σημείωση : Τυχόν ημιτελή μυνήματα προς το χρήστη δεν απασχολούν ιδιαίτερα.
    Όλος ο κώδικας :
    Spoiler:
    Κώδικας:
    #include <iostream>
    #include <limits>
    #include <vector>
    #include <functional>
    #include <algorithm>
    
    double add( double a, double b ) 	{ return a + b; }
    double sub( double a, double b ) 	{ return a - b; }
    double mul( double a, double b ) 	{ return a * b; }
    double div_( double a, double b )	{ b != 0  ? ( b = a / b ) : -1; }
    
    int main( int argc, char **argv )
    {
    	// Store the function pointers
    	using fncptr_t = std::function<double( double, double )>;
    	std::vector<fncptr_t> vFncPtr{&add, &sub, &mul, &div_};
    
    	// Store the description strings of the functions
    	std::vector<std::string> vFnDesc{"add", "sub", "mul", "div_"};
    
    	// Store the operators
    	std::vector<char> vOps{'+', '-', '*', '/'};
    
    	std::cout << "Enter + -> add, - -> sub, * -> mul, / -> div_ " << std::endl;
    	std::cout << "Enter two numbers : ";
    
    	int a, b;
    	char op;
    
    	std::cin >> a >> op >> b;
    
    	// op is now represents a mathematical operation. I have to extract it's
    	// position in order to call the corresponding function
    	std::vector<char>::iterator oper_iterator;
    	oper_iterator = std::find( vOps.begin(), vOps.end(), op );
    	if ( oper_iterator == vOps.end() )
    	{
    		std::cout << "operation " << op << " not supported" << std::endl;
    		return -1;                                                // Exit if error
    	}
    
    	// Find the number 
    	int oper_pos = std::distance( vOps.begin(), oper_iterator );
    	std::cout << "The result of your operation is : \n---\t"
    		  << vFncPtr.at( ( oper_pos ) )( a, b )
    		  << "\t---\nand you executed " << vFnDesc.at( ( oper_pos ) )
    		  << " function." << std::endl;
    	
    	return 0;
    }
    Με ΜΑΤ και βία δεν βγαίνει πανδημία, Μιχαλάκη και Κούλη.

  2. #2
    Εγγραφή
    13-11-2011
    Περιοχή
    Χολαργός
    Ηλικία
    37
    Μηνύματα
    1.451
    Downloads
    1
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    24000 / 4500
    ISP
    Wind
    DSLAM
    Wind - ΧΟΛΑΡΓΟΣ
    Path Level
    Interleaved
    Αν χρησιμοποιείς C++11 μπορείς να κάνεις:
    Κώδικας:
    enum class Section : char {
         PLUS = '+',
         MINUS = '-',
         MULT = '*',
         DIV = '/'
    };
    Αντί για 2 vector μπορείς να χρησιμοποιήσεις map.

    Στην ουσία είναι σαν ένας πίνακας που αντί για θέσεις 0,1,2,... έχει ότι του πεις εσύ και ότι τύπου θέλεις. Είναι map από μία τιμή σε μία άλλη:
    Κώδικας:
    std::map<char, fncptr_t> first;
    first['+'] = &add;
    first['-'] = &sub;
    first['*'] = &mul;
    first['/'] = &div_;
    Μετά με first[op] θα σου επιστρέφει τον function pointer.

  3. #3
    Εγγραφή
    04-02-2009
    Ηλικία
    33
    Μηνύματα
    1.486
    Downloads
    4
    Uploads
    0
    Τύπος
    ADSL
    Ταχύτητα
    2048/256
    ISP
    Cyta Hellas
    Στην προσπάθεια να αποφύγω το vector, δεν σκέφτηκα ένα καλύτερο container σε σχέση με την c-ίτιδα που χαρακτήριζε την δική μου (table-driven) λύση. Πολύ εύστοχη η ιδέα σου και πολύ πιο ...c++ φυσικά.

    Την πρώτη λύση με το enum την βρήκα και εγώ αλλά ήθελα απευθείας τους operators να είναι συσχετισμένοι με integers. Ευχαριστώ όμως, βοήθησες
    Με ΜΑΤ και βία δεν βγαίνει πανδημία, Μιχαλάκη και Κούλη.

  4. #4
    Εγγραφή
    13-11-2011
    Περιοχή
    Χολαργός
    Ηλικία
    37
    Μηνύματα
    1.451
    Downloads
    1
    Uploads
    0
    Τύπος
    VDSL2
    Ταχύτητα
    24000 / 4500
    ISP
    Wind
    DSLAM
    Wind - ΧΟΛΑΡΓΟΣ
    Path Level
    Interleaved
    Ίσως καταλαβαίνω κάτι λάθος από αυτό που θέλεις να κάνεις αλλά αν θέλεις οι operator να είναι συσχετισμένοι με integer τότε απλά κάντους cast σε unsigned int.
    Κώδικας:
    	cout << "+ = " << (unsigned int) '+' << endl;
    	cout << "- = " << (unsigned int) '-' << endl;
    	cout << "* = " << (unsigned int) '*' << endl;
    	cout << "/ = " << (unsigned int) '/' << endl;
    Ή μπορείς να τους βάλεις και σε enum με τον ίδιο τρόπο.
    Κώδικας:
    #include <iostream>
    #include <string>
    #include <map>
    using namespace std;
    
    enum operation {
    	PLUS = (int)'+',
    	MINUS = (int)'-',
    	MULTIPLY = (int)'*',
    	DIVIDE = (int)'/',
    };
    
    int main() {
    	map<peration, string> actions;
    	actions[PLUS] = "addition";
    	actions[MINUS] = "reduction";
    	actions[MULTIPLY] = "Multiplication";
    	actions[DIVIDE] = "division";
    
    	char c = '+';
    	Test op = static_cast<Test>(c);
    	cout << actions[op];
    }

  5. #5
    Εγγραφή
    04-02-2009
    Ηλικία
    33
    Μηνύματα
    1.486
    Downloads
    4
    Uploads
    0
    Τύπος
    ADSL
    Ταχύτητα
    2048/256
    ISP
    Cyta Hellas
    Πιο βαθύ μπλέξιμο μου φαίνεται. Είναι πολύ κομψή και to the point η χρήση του std::map. Έδωσες '+', επιστρέφεται ο δείκτης για την συνάρτηση που το συσχέτισες και με τον operator () εκτελείται αυτό που δείχνει. Dead simple.

    Είναι παρόλα αυτά μια τεχνική που δεν είχα σκεφτεί ούτε ήξερα. 'Ν'ν' κακό...
    Με ΜΑΤ και βία δεν βγαίνει πανδημία, Μιχαλάκη και Κούλη.

Παρόμοια Θέματα

  1. Μηνύματα: 18
    Τελευταίο Μήνυμα: 05-10-18, 11:35
  2. Συγχρονιζει σε ADSL αντι για VDSL.
    Από AlexTselikas στο φόρουμ Vodafone VDSL
    Μηνύματα: 10
    Τελευταίο Μήνυμα: 31-03-18, 00:19
  3. Μηνύματα: 51
    Τελευταίο Μήνυμα: 23-03-18, 16:17
  4. Elastix 4 ήχος μουσικής αντί για ring
    Από Marios30 στο φόρουμ Voice over IP (VoIP) Software
    Μηνύματα: 19
    Τελευταίο Μήνυμα: 03-12-17, 10:19

Bookmarks

Bookmarks

Δικαιώματα - Επιλογές

  • Δεν μπορείτε να δημοσιεύσετε νέα θέματα
  • Δεν μπορείτε να δημοσιεύσετε νέα μηνύματα
  • Δεν μπορείτε να αναρτήσετε συνημμένα
  • Δεν μπορείτε να επεξεργαστείτε τα μηνύματα σας
  •  
  • Τα BB code είναι σε λειτουργία
  • Τα Smilies είναι σε λειτουργία
  • Το [IMG] είναι σε λειτουργία
  • Το [VIDEO] είναι σε λειτουργία
  • Το HTML είναι εκτός λειτουργίας