STL vector operator()



  • MSDN:

    The function-call operator, invoked using parentheses, is a binary operator.

    primary-expression ( expression-listopt )
    In this context, primary-expression is the first operand, and expression-list, a possibly empty list of arguments, is the second operand. The function-call operator is used for operations that require a number of parameters. This works because expression-list is a list instead of a single operand. The function-call operator must be a nonstatic member function.

    The function-call operator, when overloaded, does not modify how functions are called; rather, it modifies how the operator is to be interpreted when applied to objects of a given class type. For example, the following code would usually be meaningless:

    Point pt;
    pt( 3, 2 );
    Given an appropriate overloaded function-call operator, however, this syntax can be used to offset the x coordinate 3 units and the y coordinate 2 units. The following code shows such a definition:

    // function_call.cpp
    class Point
    {
    public:
    Point() { _x = _y = 0; }
    Point &operator()( int dx, int dy )
    { _x += dx; _y += dy; return *this; }
    private:
    int _x, _y;
    };

    int main()
    {
    Point pt;
    pt( 3, 2 );
    }
    Note that the function-call operator is applied to the name of an object, not the name of a function.

    Wenns dir darum geht, das SO nutzen zu können, kannst du es ja versuchen. Ich wäre damit allerdings vorsichtig. Im Zweifelsfall solltest du (wie es die STL mit "at()" ja vormacht) einen kurzen, sprechenden Funktionsnamen verwenden und operator() in Ruhe lassen.



  • hm hmm hmmm 😕

    also mir leuchtet irgendwie nicht so recht ein, was das Beispiel Point hier mit der Klasse Vector zu tun hat.
    Innerhalb der Klasse Point wird hier ja doch operator() definiert! 😮
    Aber ich kann ja schlecht in der Klasse Vector rumfummeln, sondern hab eben versucht von außen mir diesen operator() zu definieren/überladen.

    Was ist denn konkret falsch, wenn ich in meiner
    test.hpp
    das hier schreib:

    inline int std::vector< int >::operator()(int i, int j){
    	return i*j;
    }
    

    Mein VS Compiler meint jedenfalls nur

    '()': Ist kein Element von 'std::vector<_Ty>'
    1> with
    1> [
    1> _Ty=int
    1> ]

    Aber ich will mir diesen operator ja doch neu definieren! 😡



  • Du kannst nicht einfach eine bestehende Implementierung verändern, das wäre ziemlich am Open-Closed Prinzip vorbei, selbst wenn vector einen operator() hätte (was er nicht hat).



  • ohh ok 🙄
    aber heißt das wohl auch, dass ich mir diesen operator nicht innerhalb meiner Klasse definieren darf ?
    Was bliebe denn da noch ??

    Dankeschön 🙂

    GiantGeorge



  • Innerhalb deiner Klasse kannst du definieren was du willst. Nur ableiten von std::vector ist, wie gesagt, keine gute Idee. Die STL Container haben (alle??) keine virtuellen Destruktoren, was zu bescheuerten Problemen führen kann...

    grüße



  • huch,
    leite ich wohl mit dieser Anweisung von Vector ab ?

    inline int std::vector< int >::operator()(int i, int j){
        return i*j;
    }
    

    Was kann ich denn überhaupt konkret machen, ohne abzuleiten ?
    Am liebsten Code, weil ich grad noch dermaßen ohne Plan bin.
    😞

    Also schon mal Danke!



  • Nein, damit definierst du eine nichtdeklarierte Methode für die Klasse vector<> - und das ist verboten. (und versuch lieber nicht, in den Standard-Headern rumzupfuschen)

    PS: Und Ableitung ist afaik die einzige Möglichkeit, einer vector-Abart eine neue Methode zu spendieren.

    PPS: Was soll dieser operator eigentlich im Endeffekt bewirken? So ein "return i*j;" hat imho nichts in der Containerklasse zu suchen.



  • PS: Und Ableitung ist afaik die einzige Möglichkeit, einer vector-Abart eine neue Methode zu spendieren.

    ohne virtuellen dtor wär das ziemlicher müll, ausser man leitet private ab. aber dann könnte man genausogut vector als member nehmen.



  • Also, im Prinzip umfasst dieser Vektor Zellen eines 3-dimensionalen Gebietes.
    Nun habe ich periodische Randbedingungen, d.h. wird versucht auf eine Zelle außerhalb des Gebietes zuzugreifen, z.B. die Zelle direkt links vom linken Rand, so soll stattdessen die Zelle INNERHALB des Gebietes, also direkt links vom rechten Rand, zurückgegeben werden.

    Der Code schaut prinzipiell dann folgendermaßen aus:

    class Grid{
        public:
    		std::vector< cell > cellVec;
    
    		//Access operator
    		inline cell std::vector< cell >::operator()( int i, int j, int k );
    
    		void accessCells();
    
        private:
    
    		//Number of Cells in x, y and z-direction
            const int nx;
            const int ny;
            const int nz;		
    
    		inline vector Grid::operator()( uint i, uint j, uint k )
    		{
    			//Treatment of the periodic boundary condtions
    			if( k < 0 ) k += nz;
    			else if( k >= nz ) k -= nz;
    			if( j < 0 ) j += ny;
    			else if( j >= ny ) j -= ny;
    			if( i < 0 ) i += nx;
    			else if( i >= nx ) i -= nx;
    
                      // cellVec is 1-dim 
    			return cellVec[i+(j+k*ny)*nx];
    		}		
    };
    
    void Grid::accessCells()
    {
    	for(uint k=0; k<nz; ++k){
            for(uint j=0; j<ny; ++j){
                for(uint i=0; i<nx; ++i){
    				// access somehow on neighbor cells
    				cellVec(i,j-1,k).F = cellVec(i,j,k).F;
    			}
    		}
    	}
    }
    

    Spricht wirklich so viel gegen Ableitung ?
    Im moment würde ich nämlich gerne wie CStoll sagt, dieser vector-Abart eine neue Methode spendieren. 😉

    Lieben Gruß,
    GiantGeorge



  • Das kannst du doch auch in deine Grid-Klasse packen. Die hat doch schon einen vector als Member. Den machst du am besten auch noch private und schreibst dir entsprechende Zugriffsfunktionen.



  • mhhh, ich kann mir nicht vorstellen wie das mit diesen Zugriffsfunktionen aussehen soll.
    Braunstein, wärest du noch so nett und würdest mir ein Code Beispiel geben ? 🙄



  • Du hast doch schon eine. Den operator() deiner Grid-Klasse. Die Funktion hat nur den falschen Rückgabetyp (vielleicht nur verschrieben, das würde so nicht compilieren).

    cell Grid::operator()( uint i, uint j, uint k ) const
    {...
    

    Das inline ist hier unnötig. Die Klasse (oder struct) cell muß natürlich kopierbar sein. Man könnte hier auch ein const cell& zurückgeben. Wenn du in diesen Vector schreiben willst brauchst du halt noch eine Funktion, die eine Referenz auf ein vector-Element zurückgibt.



  • also, klappt wunderbar jetzt ! 🙂
    Danke an alle für die Hilfe !

    Gruß,
    GiantGeorge


Anmelden zum Antworten