Archived

This topic is now archived and is closed to further replies.

Floating

Ununderstandable template error..

Recommended Posts

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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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")

Share this post


Link to post
Share on other sites
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[i]);
}

//------------------------------------------------------------

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
... 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]

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites