How to eliminate assignment operator generation warning

  • Thread starter Thread starter tron.thomas
  • Start date Start date
T

tron.thomas

I'm using Microsoft Development Environment 2002 Version 7.0.9466 on
Windows XP Professional Service Pack 2. If I compile the following
code at maximum warning level:

#include <functional>

class SetValue : public std::unary_function<int, void>
{
public:
explicit SetValue(int& value) : m_value(value) {}
void operator() (int value) { m_value = value; }
private:
int& m_value;
};


I get the following warning:
.... warning C4512: 'SetValue' : assignment operator could not be
generated
... see declaration of 'SetValue'

I can't see anything in the declaration of this class that would
prevent the compiler from generating an assignment operator.

What is causing the warning and how can I eliminate it?
 
I'm using Microsoft Development Environment 2002 Version 7.0.9466 on
Windows XP Professional Service Pack 2. If I compile the following
code at maximum warning level:
...
I get the following warning:
... warning C4512: 'SetValue' : assignment operator could not be
generated
... see declaration of 'SetValue'

FWIW, the Comeau online compiler agrees with VC++ - it reports a more
useful message:

"ComeauTest.c", line 3: error: implicitly generated assignment
operator cannot copy:
reference member "SetValue::m_value"
What is causing the warning and how can I eliminate it?

Add an assignment operator to the class.

Dave
 
Hi tron!
class SetValue : public std::unary_function<int, void>
{
public:
explicit SetValue(int& value) : m_value(value) {}
void operator() (int value) { m_value = value; }
private:
int& m_value;
};

Is this a good idea to store a pointer to a value?

I would only do: int m_value;

Or what is the reason for this?

--
Greetings
Jochen

My blog about Win32 and .NET
http://blog.kalmbachnet.de/
 
What is the reason the reference variable m_value cannot be copied? As
far as I know there should be no problem with this. It is perfectly
legal to do the following:

int value = 42;
int& first = value
int& second = first; // copy of the first reference
 
Tron said:
What is the reason the reference variable m_value cannot be copied?
As far as I know there should be no problem with this. It is
perfectly legal to do the following:

References cannot be copied. Ever.
int value = 42;
int& first = value
int& second = first; // copy of the first reference

Not really a copy of the first reference, but a new reference to 'value'.

Here's the case that matters though:

int value;
int& first = value;
int other;
int& second = other;

// legal, but doesn't assign the reference
// instead, 'other' is set to the same value as 'value'.
second = first;

-cd
 
The example I posted was meant to be a simpler example of the real
functor I'm using that is creating the warning. The following is more
or less what I'm trying to do, only I'm not using integers:

class UpdateBounds : public std::unary_function<int, void>
{
public:
UpdateBounds(int* pMaxValue, int* pMinValue) :
m_maxValue(*pMaxValue), m_minValue(*pMinValue) {}
void operator ()(int value)
{
if(value > m_maxValue){
m_maxValue = value;
}
else if(value < m_minValue){
m_minValue = value;
}
}
private:
int& m_maxValue;
int& m_minValue;
};

typedef std::vector<int> IntVector;
typedef IntVector::iterator IntIterator;

IntVector values;
// Populate the values ...

IntIterator itBegin = values.begin();
int maxValue = *itBegin;
int minValue = maxValue;

std::for_each(++itBegin, values.end(), UpdateBounds(&maxValue,
&minValue));


After this code has completed, the maxValue and minValue variables will
contain the maximum and minimum values (i.e. the bounds)respectively of
the values vector with only one pass through that vector.

If there is a better way to accomplish this, please let me know. Also,
please excuse any errors in the above code. I did not compile it to
make sure it was correct.
 
Right, in my original test, I confused assignment with initialization.

With the original code I posted someone could do the following:

int value = 42;
SetValue functor(value);
SetValue anotherFunctor = functor; // this is initialization, not
assignment.

Someone cannot do this:
int anotherValue = 13;
SetValue anotherFunctor(anotherValue);
anotherFunctor = functor; // this is assignment and will fail because
the reference can't be assigned to refer to something else

I don't need or want the functor to be assigned to another functor, so I
will just declare a private assignment operator and not provide any
implementation.
 
Tron said:
Right, in my original test, I confused assignment with initialization.

With the original code I posted someone could do the following:

int value = 42;
SetValue functor(value);
SetValue anotherFunctor = functor; // this is initialization, not
assignment.

Someone cannot do this:
int anotherValue = 13;
SetValue anotherFunctor(anotherValue);
anotherFunctor = functor; // this is assignment and will fail because
the reference can't be assigned to refer to something else

I don't need or want the functor to be assigned to another functor,
so I will just declare a private assignment operator and not provide
any implementation.

That's the appropriate solution to eliminate the warning.

-cd
 
Tron Thomas wrote:

[snip code for algorithm to calculate min and max element of a sequence
using for_each]
If there is a better way to accomplish this, please let me know. Also,
please excuse any errors in the above code. I did not compile it to
make sure it was correct.

I think a better approach would be to write a min_max_element algorithm,
that would return a std::pair<It, It>. e.g.

template <class FwdIt>
std::pair<FwdIt, FwdIt> min_max_element(FwdIt begin, FwdIt end)
{
std::pair<FwdIt, FwdIt> min_max(begin, begin);
for (; begin != end; ++begin)
{
if (*begin < *min_max.first)
min_max.first = begin;
else if (*min_max.second < *begin)
min_max.second = begin;
}
return min_max;
}

You could also add an overload taking a predicate. Finally, if you
prefer, you could just use std::min_element and std::max_element, but
that would be a two pass approach.

As a general rule, don't use for_each if a more appropriate algorithm
exists (or you can write one).

Tom
 
Back
Top