473,406 Members | 2,698 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

error: passing `const ...' as `this' argument of `...' discardsqualifiers

Hello,

I'm doing some toy experiments to see how
the algoritm std::transform and the function
adapter std::bind2nd can play together, but
my compiler give my the error

error: passing `const traslate' as `this' argument of
`circle traslate::operator()(circle, std::vector<double,
std::allocator<double)'
discards qualifiers

It should be like I'm trying to modify
something which is declared as const...

The example code follows.

I define the type `circle', which holds
center and radius of a circle, then I
introduce a vector of circles and try to
traslate them all with std::transform.
I need std::bind2nd to fix the traslation
for all the circles.
Note that I'm forced to define the
temporary object `traslate' to meet
std::bind2nd input specifications.

// =======================================
#include <vector>
#include<functional>
#include<algorithm>
using namespace std;

struct circle
{
vector<doublecenter;
double radius;
};

struct traslate
{
typedef circle first_argument_type;
typedef vector<doublesecond_argument_type;
typedef circle result_type;
circle operator()(const circle original, const vector<double>
traslation)
{
circle traslated = original;
traslated.center[0] += traslation[0];
traslated.center[1] += traslation[1];
return traslated;
}
};

int main()
{
vector<circlelots_of_circles(10);
vector<circlesome_other_circles(10);
vector<doubletraslation(2);
traslation[0] = 123;
traslation[1] = 321;
transform(lots_of_circles.begin(), lots_of_circles.end(),
some_other_circles.begin(), bind2nd(traslate(), traslation));
}
// =======================================

Can you see the reason of the above mentioned error?

Regards,
Giovanni Gh.
Aug 12 '08 #1
4 6145
On Aug 12, 9:23*am, Giovanni Gherdovich
<gherdov...@students.math.unifi.itwrote:
Hello,

I'm doing some toy experiments to see how
the algoritm std::transform and the function
adapter std::bind2nd can play together, but
my compiler give my the error

error: passing `const traslate' as `this' argument of
`circle traslate::operator()(circle, std::vector<double,
std::allocator<double)'
discards qualifiers

It should be like I'm trying to modify
something which is declared as const...

The example code follows.

I define the type `circle', which holds
center and radius of a circle, then I
introduce a vector of circles and try to
traslate them all with std::transform.
I need std::bind2nd to fix the traslation
for all the circles.
Note that I'm forced to define the
temporary object `traslate' to meet
std::bind2nd input specifications.

// =======================================
#include <vector>
#include<functional>
#include<algorithm>
using namespace std;

struct circle
{
* vector<doublecenter;
How about std::pair instead? Or, perhaps even better, make your own
point class with members x and y. std::vector is overkill here.
* double radius;

};

struct traslate
{
*typedef circle first_argument_type;
*typedef vector<doublesecond_argument_type;
*typedef circle result_type;
Consider inheriting from std::binary_function instead of this.
*circle operator()(const circle original, const vector<double>
traslation)
You probably want to use references for both of these parameters to
prevent unnecessary copies. (They may be inlined away or relatively
trivial here, but maybe not if you call this a lot.) You should also
use std::pair or your own point class here, too, since you only have x
and y coordinates. Since this function doesn't modify the object's
state, it should be made const (note also the references):

circle operator()(
const circle& original,
const vector<double>& traslation) const
{ ... }

However, since your functor has no state, you should just make this a
plain old function rather than a function object.
*{
* *circle traslated = original;
* *traslated.center[0] += traslation[0];
* *traslated.center[1] += traslation[1];
* *return traslated;
*}

};

int main()
{
* vector<circlelots_of_circles(10);
* vector<circlesome_other_circles(10);
* vector<doubletraslation(2);
* traslation[0] = 123;
* traslation[1] = 321;
* transform(lots_of_circles.begin(), lots_of_circles.end(),
some_other_circles.begin(), bind2nd(traslate(), traslation));}

// =======================================

Can you see the reason of the above mentioned error?
You're creating a temporary object -- the instance of translate --
which is bound to a const reference in bind2nd. The function you are
calling is not const. Add const to the member function, or better,
make it a plain old function.

See these FAQs for more info on const-correctness:

http://www.parashift.com/c++-faq-lit...rrectness.html

Cheers! --M
Aug 12 '08 #2
Thank you; you answer even more than
what I've asked and I appreciate it a lot.
struct circle
{
vector<doublecenter;

How about std::pair instead
I agree. And since I don't need any method
for these points, std::pair will do the job.
struct traslate
{
typedef circle first_argument_type;
typedef vector<doublesecond_argument_type;
typedef circle result_type;

Consider inheriting from std::binary_function
instead of this.
Cool!
So I can avoid to explicitly rename my types with the
tedious

typedef circle first_argument_type;
typedef vector<doublesecond_argument_type;
typedef circle result_type;
However, since your functor has no state, you should just make this a
plain old function rather than a function object.
True, but if I do that I cannot use the algorithm std::tranform,
wich save me from looping explicitly over the circles (wich I
find is cool), because I cannot use std::bind2nd
(which wants a function object as first argument).
You're creating a temporary object -- the instance of translate --
which is bound to a const reference in bind2nd. The function you are
calling is not const. Add const to the member function
Exactly.
Thank you, also for the reference to the FAQs.

But let me understand: std::bind2nd onbly accept _const_ member
functions a input function object?

Cheers,
Giovanni
Aug 12 '08 #3
On Aug 12, 10:57*am, Giovanni Gherdovich
<gherdov...@students.math.unifi.itwrote:
How about std::pair instead

I agree. And since I don't need any method
for these points, std::pair will do the job.
Right, though struct Point { double x,y; }; may make your code easier
to read and only requires reinventing a very, very small wheel. :-)
However, since your functor has no state, you should just make this a
plain old function rather than a function object.

True, but if I do that I cannot use the algorithm std::tranform,
wich save me from looping explicitly over the circles (wich I
find is cool), because I cannot use std::bind2nd
(which wants a function object as first argument).
With ordinary functions, just use std::ptr_fun to wrap them for
std::transform et al.:

circle Translate1( const circle original, const vector<double>
traslation)
{ /* code from traslate::operator() */ }

// ...
transform(lots_of_circles.begin(), lots_of_circles.end(),
some_other_circles.begin(),
bind2nd(ptr_fun(Translate), traslation));

You may notice I omitted the references from the parameters to
Translate1 because, unfortunately, the standard binders currently
don't allow reference arguments. For more on this problem, see
http://www.boost.org/doc/libs/1_35_0...raits.htm#refs

Alternately, if you have the standard library extensions known as TR1
or if you have Boost (where most of those extensions originated), you
could use reference arguments with the generalized binder
(std::tr1::bind or boost::bind) instead of std::bind2nd:

// Note ref params
circle Translate2( const circle& original, const vector<double>&
traslation)
{/*same code*/}

// ...

// TR1 version
transform(lots_of_circles.begin(), lots_of_circles.end(),
some_other_circles.begin(),
std::tr1::bind(
Translate2,
std::tr1::placeholders::_1,
traslation) );

// Easier-to-read version of the above:
using namespace std::tr1;
using namespace std::tr1::placeholders;

transform(lots_of_circles.begin(), lots_of_circles.end(),
some_other_circles.begin(), bind( Translate2, _1, traslation) );
// Boost version
transform(lots_of_circles.begin(), lots_of_circles.end(),
some_other_circles.begin(), boost::bind(Translate2, _1,
traslation) );

For more on these, see Pete Becker's article:

http://www.ddj.com/cpp/184401949

or his book on TR1, or the Boost.Bind documentation.
But let me understand: std::bind2nd onbly accept _const_ member
functions a input function object?
Yes. The enhanced binders correct this and other "inconveniences" with
the standard binders.

Cheers! --M
Aug 12 '08 #4
Dear Mlimber,
However, since your functor has no state, you should just make this a
plain old function rather than a function object.
True, but if I do that I cannot use the algorithm std::tranform,
wich save me from looping explicitly over the circles (wich I
find is cool), because I cannot use std::bind2nd
(which wants a function object as first argument).

With ordinary functions, just use std::ptr_fun to wrap them for
std::transform et al.:
this information is precious.
I was wondering how to use std::bind2nd without building
ad-hoc function object...
You may notice I omitted the references from the parameters to
Translate1 because, unfortunately, the standard binders currently
don't allow reference arguments. For more on this problem, see
http://www.boost.org/doc/libs/1_35_0...raits.htm#refs

Alternately, if you have the standard library extensions known as TR1
or if you have Boost
Mmmh... I was not aware of that.
I may have to review my design, or to use Pete Becker's TR1 or Boost
as you suggest.
The point is that I have to call a code analogous to the circles'
one...
a few millions of times.
And as you told,
You probably want to use references for both of these parameters to
prevent unnecessary copies. (They may be inlined away or relatively
trivial here, but maybe not if you call this a lot.)
I will study this issue.

Cheers,
Giovanni
Aug 13 '08 #5

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
by: Alex Vinokur | last post by:
Various forms of argument passing ================================= C/C++ Performance Tests ======================= Using C/C++ Program Perfometer...
58
by: jr | last post by:
Sorry for this very dumb question, but I've clearly got a long way to go! Can someone please help me pass an array into a function. Here's a starting point. void TheMainFunc() { // Body of...
5
by: xuatla | last post by:
Hi, I encountered the following compile error of c++ and hope to get your help. test2.cpp: In member function `CTest CTest::operator+=(CTest&)': test2.cpp:79: error: no match for 'operator='...
17
by: Charles Sullivan | last post by:
The library function 'qsort' is declared thus: void qsort(void *base, size_t nmemb, size_t size, int(*compar)(const void *, const void *)); If in my code I write: int cmp_fcn(...); int...
33
by: Martin Jørgensen | last post by:
Hi, In continuation of the thread I made "perhaps a stack problem? Long calculations - strange error?", I think I now got a "stable" error, meaning that the error always seem to come here now...
4
by: Lycan. Mao.. | last post by:
Hello, I'm trying to write a function adapter object, but it fails with the above information. Can you help me. template <typename _Predicate> struct Unary_negate { typedef typename...
3
by: alishapal | last post by:
Hi there So I am getting these error messages from Intel (v10) and g++ (v4.1.2) compilers respectively: "error: the object has cv-qualifiers that are not compatible with the member function. object...
6
by: jma | last post by:
Hi all, I want to push some errors on an error stack in my function. The first parameter of the push function is the name of the function where the error occured. For example: int...
8
by: Ruben | last post by:
error: passing `const Weight' as `this' argument of `float Weight::wgt()' discards qualifiers seems to be some sort of standard error format that I'm not understanding. I have code that...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.