Ununderstandable template error..

Started by
7 comments, last by Floating 20 years ago
Hi Suddenly I can't compile my application anymore (MSVC++6)and I can't understand the error messages which are: C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\xutility(39) : error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'const class C3Vector' (or there is no acceptable conversion) C:\Program Files\Microsoft Visual Studio\VC98\INCLUDE\vector(170) : see reference to function template instantiation 'void __cdecl std::fill(class C3Vector *,class C3Vector *,const class C3Vector &)' being compiled I didn't modify the files xutility nor vector, but I did some other modifications is my application. Where does the error originate from? How can I find out what I have to change in my files? Thanks EDIT: I could find where the error originated from, but can't understand why: I have: std::vector faceNormals; faceNormals.push_back(C3Vector(3.0f,0.0f,0.0f)); [edited by - Floating on April 5, 2004 11:04:35 PM]
Advertisement
Are you sure that''s the right line? Apparently you''re calling the function std::fill from the file <algorithm>. Post the code that calls that. My best guess is that you have a reference where you should have a pointer or vice-versa. std::fill takes three pointer arguments, but you''re passing two pointers and a reference, according to the error message. Try adding a ''&'' before the third argument to std::fill.
Thanks for your reply.

It has to be in that line because if I comment it out, it compiles fine (and I never call std::fill... somehow "fill" is called inside "push_back")
I tried the whole day but couldn''t find the reason for that error... (;_

What I don''t understand is that following doesn''t give me an error:

std::vector a;
CPoint b;
a.push_back(b);

but following gives me that error:

std::vector a;
C3Vector b;
a.push_back(b);

Something in the header of C3Vector is probably wrong, but what is it?

Here the header:

class C3X3Matrix; // Forward declaration
class C4X4Matrix; // Forward declaration
class C7Vector; // Forward declaration

class C3Vector
{
public:

//------------------- Construction/destruction ---------------
C3Vector();
C3Vector(float v0,float v1,float v2);
C3Vector(C3Vector& v);
virtual ~C3Vector();
//------------------------------------------------------------

//------------------- Various functions ----------------------
void clear();
float getLength();
float getAngle(C3Vector& v);
bool isColinear(C3Vector& v);
//------------------------------------------------------------

//------------------- Operator overloading -------------------
C3Vector operator/ (float d);
C3Vector operator* (float d);
C3Vector operator+ (C3Vector& v);
C3Vector operator- (C3Vector& v);
C3Vector operator^ (C3Vector& v);

void operator/= (float d);
void operator*= (float d);
void operator+= (C3Vector& v);
void operator-= (C3Vector& v);
void operator^= (C3Vector& v);

void operator*= (C4X4Matrix& m);
void operator*= (C3X3Matrix& m);
void operator*= (C7Vector& transf);

float& operator() (unsigned i);
const float& operator() (unsigned i) const;
float operator* (C3Vector& v);
C3Vector& operator= (C3Vector& v);
//------------------------------------------------------------

//------------------- Private variables ----------------------
private:
float data[3];
//------------------------------------------------------------
};

//------------------- Inlined functions ----------------------

inline bool C3Vector::isColinear(C3Vector& v)
{
float scalProdSq=(*this)*v;
scalProdSq=scalProdSq*scalProdSq;
float l1=(*this)*(*this);
float l2=v*v;
return((scalProdSq/(l1*l2))>0.99999f);
}

inline float& C3Vector::operator() (unsigned i)
{
SIM_ASSERT(i<3);
return(data);
}

inline const float& C3Vector::operator() (unsigned i) const
{
SIM_ASSERT(i<3);
return(data);<br>}<br><br>//———————————————————— </i>
Try changing
C3Vector(C3Vector& v); 

to
C3Vector(const C3Vector& v); 


It makes sense to do that anyway since in most cases you shouldn''t be able to modify what you''re copying from in a copy constructor.
"Voilà! In view, a humble vaudevillian veteran, cast vicariously as both victim and villain by the vicissitudes of Fate. This visage, no mere veneer of vanity, is a vestige of the vox populi, now vacant, vanished. However, this valorous visitation of a bygone vexation stands vivified, and has vowed to vanquish these venal and virulent vermin vanguarding vice and vouchsafing the violently vicious and voracious violation of volition. The only verdict is vengeance; a vendetta held as a votive, not in vain, for the value and veracity of such shall one day vindicate the vigilant and the virtuous. Verily, this vichyssoise of verbiage veers most verbose, so let me simply add that it's my very good honor to meet you and you may call me V.".....V
You''re not telling us something about the original problem. You were calling the following function. Note the signature - it takes a const T&, so your C3Vector is actually passed in as a const C3Vector& (and rightly so).

template <class ForwardIterator, class T>void fill(ForwardIterator first, ForwardIterator last, const T& value);


Now this will assign the value using operator=. Your operator= defined for C3Vector takes a non-const C3Vector&, and the compiler won''t just automatically remove the const safety.

What you need to do is define operator= to take a const C3Vector&.

Similarly for the constructor.
... and also your other operators.

Otherwise this won't compile:

const C3Vector a;
const C3Vector b;

C3Vector c = a + b;//operator+ is defined by you to not take a const C3Vector&
//normal practice is to pass by const reference arguments that won't be modified

[edited by - petewood on April 6, 2004 6:57:28 AM]
Thanks a lot!! Compiling now
This forced me to learn a bit more about "const". I never really used it (nor needed it), but now I see its usefulness.

So basically my header looks like:

...
C3Vector operator/ (float d) const;
C3Vector operator* (float d) const;
C3Vector operator+ (const C3Vector& v) const;
...

does it also make sense to write for instance:

C3Vector operator/ (const float d) const;
or
C3Vector operator/ (const float* d) const;

? I don''t think so (the parameter d will fist be copied before used in the first function), but the compiler doesn''t complain neither.
Actually, looking at your code more carefully, I think you should learn about class design. operator+ shouldn''t return void. Take a look at your documentation for std::complex to see the normal way of designing a class. Look at the implementation to see what''s going on inside.

This topic is closed to new replies.

Advertisement