error: no match for ‘operator=’

I'm writing a small openGL program to do keyframe animation. The lines of code I have highlighted in my code appear responsible for the error I get when compiling (full output below).

I'd like to know why this is wrong, and also any suggestions as to how to do it differently.

Cheers, Chris

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

class Vector3f {
	float _item[3];
	public: //.......
// Vector3f is just a simple array of floats with a rotation function.
// I don't think it's relevant to this problem.
}


struct Keyframe{
    int frameid;
    Vector3f rotation;
};

struct AnimTrack {
    int trackid;
    vector <Keyframe>  _keyFrames;
};



class Animation {
    int numFrames;
    int currentFrame;
    int numJoints;
    
    vector <AnimTrack> _tracks;   
    
public:
    Animation(){};
    
    void setNumFrames(int frames){ numFrames = frames;}
    
    int getNumFrames() {return numFrames;}
   
    int getnumJoints(){return numJoints;} 
    
    void addAnimtrack(AnimTrack &track){
         _tracks.push_back(track);
    }        
};


error:
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h: In static member function ‘static _OI std::__copy<_BoolType, std::random_access_iterator_tag>::copy(_II, _II, _OI) [with _II = const Keyframe*, _OI = Keyframe*, bool _BoolType = false]’:
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:317: instantiated from ‘_OI std::__copy_aux(_II, _II, _OI) [with _II = const Keyframe*, _OI = Keyframe*]’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:354: instantiated from ‘static _OI std::__copy_normal<true, true>::copy_n(_II, _II, _OI) [with _II = __gnu_cxx::__normal_iterator<const Keyframe*, std::vector<Keyframe, std::allocator<Keyframe> > >, _OI = __gnu_cxx::__normal_iterator<Keyframe*, std::vector<Keyframe, std::allocator<Keyframe> > >]’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:387: instantiated from ‘_OutputIterator std::copy(_InputIterator, _InputIterator, _OutputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const Keyframe*, std::vector<Keyframe, std::allocator<Keyframe> > >, _OutputIterator = __gnu_cxx::__normal_iterator<Keyframe*, std::vector<Keyframe, std::allocator<Keyframe> > >]’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/vector.tcc:152: instantiated from ‘std::vector<_Tp, _Alloc>& std::vector<_Tp, _Alloc>::operator=(const std::vector<_Tp, _Alloc>&) [with _Tp = Keyframe, _Alloc = std::allocator<Keyframe>]’
anim.h:197: instantiated from ‘void std::vector<_Tp, _Alloc>::_M_insert_aux(__gnu_cxx::__normal_iterator<typename std::_Vector_base<_Tp, _Alloc>::_Tp_alloc_type::pointer, std::vector<_Tp, _Alloc> >, const _Tp&) [with _Tp = AnimTrack, _Alloc = std::allocator<AnimTrack>]’
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_vector.h:610: instantiated from ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) [with _Tp = AnimTrack, _Alloc = std::allocator<AnimTrack>]’
anim.h:221: instantiated from here
/usr/lib/gcc/i386-redhat-linux/4.1.2/../../../../include/c++/4.1.2/bits/stl_algobase.h:285: error: no match for ‘operator=’ in ‘* __result = * __first’
anim.h:192: note: candidates are: Keyframe& Keyframe::operator=(Keyframe&)



Last edited on
What else is in struct Keyframe and Vector3f?
There is nothing else in Keyframe at present, this is the full Vector3f Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
class Vector3f {

	float _item[3];

	public:

	float & operator [] (int i) {
		return _item[i];
    	}

	Vector3f(float x, float y, float z) 
	{  _item[0] = x ; _item[1] = y ; _item[2] = z; };

	Vector3f() {};


	Vector3f & operator = (Vector3f & obj) 
	{
		_item[0] = obj[0];
		_item[1] = obj[1];
		_item[2] = obj[2];

		return *this;
	};

	Vector3f & operator += (Vector3f & obj) 
	{
		_item[0] += obj[0];
		_item[1] += obj[1];
		_item[2] += obj[2];

		return *this;
	};
	
	//Eulerian rotation about X, Y, and Z axes in that order.
	void rotateXYZ(float angleX, float angleY, float angleZ, Vector3f & center){
		float offset[3];
		float ret[3];
		
		offset[0]=_item[0]-center[0];
		offset[1]=_item[1]-center[1];
		offset[2]=_item[2]-center[2];
		
		
		//Rotate around X
		ret[0] = offset[0];
		ret[1] = offset[1]*cos(angleX) + offset[2]*sin(angleX);
		ret[2] = offset[2]*cos(angleX) - offset[1]*sin(angleX);
		
		//Rotate around Y
		_item[0] = ret[0]*cos(angleY) - ret[2]*sin(angleY);
		_item[1] = ret[1];
		_item[2] = ret[0]*sin(angleY) + ret[2]*cos(angleY);
	
		//Rotate around Z
		ret[0] = _item[0]*cos(angleZ) + _item[1]*sin(angleZ);
		ret[1] = _item[1]*cos(angleZ) - _item[0]*sin(angleZ);
		ret[2] = _item[2];

		_item[0] = ret[0]+center[0];
		_item[1] = ret[1]+center[1];
		_item[2] = ret[2]+center[2];
	};
};
I managed to find someone who could help me on this one. Here's the fix:

Changed _tracks to be a vector of pointers to AnimTracks, and changed addAnimtrack take a pointer as a parameter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Animation {
    int numFrames;
    int currentFrame;
    int numJoints;
    
    vector <AnimTrack *> _tracks;   
    
public:
    Animation(){};
    
    void setNumFrames(int frames){ numFrames = frames;}
    
    int getNumFrames() {return numFrames;}
   
    int getnumJoints(){return numJoints;} 
    
    void addAnimtrack(AnimTrack* track){
         _tracks.push_back(track);
    }        
};


You didn't fix the problem, you masked it.

Try changing Vector3f's assignment operator to a more correct declaration:

 
Vector3f& operator=( const Vector3f& rhs ) { /* ... */ }


and see if that fixes the compile error.

I changed the operator as you suggested, and it works fine now. I'm still not entirely sure why the const makes such a difference, so i'm back to my books to find out.

Cheers.
Because there is a little clause in the standard that says you cannot bind temporaries to non-const references. A simple example:

1
2
3
4
5
6
7
8
9
10
11
12
#include <string>
#include <iostream>

using namespace std;

void print_me( string& s ) {
    cout << s << endl;
}

int main() {
   print_me( string( "Hello World" ) );
}


generates a compile error because the string( "Hello World" ) is a
temporary object that is being passed to a function that accepts a (non-const)
reference. To fix the compile error, print_me should take its parameter by const
reference. The standard allows for temporaries to be bound to const references.

This is exactly the problem you were having.
Topic archived. No new replies allowed.