473,385 Members | 1,546 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,385 software developers and data experts.

Function object, this and constructor

This similar situation will explain somewhat, what I want to do:

class X {
public:
X() : map_(*this) {}

bool operator() (int a, int b) { return goodStuff(a) <
goodStuff(b); }
int goodStuff(int a) { ... }

private:
map<int, int, Xmap_;
};

Why do I want this? Because the goodStuff function is already there
and I don't want to write it twice. This piece of code doesn't work as
one would expect. I also tried doing things like

class X {
public:
X() : map_( ptr_fun(&X::stuff) ) {}

bool stuff(int a, int b) const { return goodStuff(a) <
goodStuff(b); }

private:
map< int, int, binary_function<int, int, bool map_;
};

but this works neither. Is there a way to do this thing. The X objects
are a pain to construct (lots of big stuff in 'em) so I don't want to
generate them anymore than I have to. I guess that second could be
made to work if the goodStuff would be static, but it ain't.

This isn't a stopper problem, I know a way around this (problem-
specific), but it stinks. I want to know how to do this "the way it
should be done".

Jul 8 '07 #1
5 1526
vulpes wrote:
This similar situation will explain somewhat, what I want to do:

class X {
public:
X() : map_(*this) {}

bool operator() (int a, int b) { return goodStuff(a) <
goodStuff(b); }
int goodStuff(int a) { ... }

private:
map<int, int, Xmap_;
};
So you construct the map<int,intvariable from the X class.
Take a look here what are map constructors expecting:
http://www.cppreference.com/cppmap/m...structors.html
>
Why do I want this? Because the goodStuff function is already there
and I don't want to write it twice. This piece of code doesn't work as
one would expect. I also tried doing things like

class X {
public:
X() : map_( ptr_fun(&X::stuff) ) {}

bool stuff(int a, int b) const { return goodStuff(a) <
goodStuff(b); }

private:
map< int, int, binary_function<int, int, bool map_;
};
What is ptr_fun?
Here is the same as the previous. You want to construct the map<int,int>
object from ptr_fun (whatever that is)

>
but this works neither. Is there a way to do this thing. The X objects
are a pain to construct (lots of big stuff in 'em) so I don't want to
generate them anymore than I have to. I guess that second could be
made to work if the goodStuff would be static, but it ain't.

This isn't a stopper problem, I know a way around this (problem-
specific), but it stinks. I want to know how to do this "the way it
should be done".
You message was not clear enough for me to understand what exactly you
want to do.
Why your solution stinks?
Jul 9 '07 #2
On Jul 9, 1:11 am, vulpes <ntv...@luukku.comwrote:
This similar situation will explain somewhat, what I want to do:
class X {
public:
X() : map_(*this) {}
bool operator() (int a, int b) { return goodStuff(a) <
goodStuff(b); }
int goodStuff(int a) { ... }
private:
map<int, int, Xmap_;
};
Why do I want this? Because the goodStuff function is already there
and I don't want to write it twice. This piece of code doesn't work as
one would expect.
What would one expect? It's undefined behavior. (I expect that
it will not compile with most implementations. I can't think of
any reasonable implementation of map where the class itself
doesn't contain an instance of the comparator. So what you've
written is that X contains a map which contains an X...)
I also tried doing things like
class X {
public:
X() : map_( ptr_fun(&X::stuff) ) {}
bool stuff(int a, int b) const { return goodStuff(a) <
goodStuff(b); }
private:
map< int, int, binary_function<int, int, bool map_;
};
but this works neither. Is there a way to do this thing.
The obvious (but not necessarily good) solution is to replace
the map with a pointer to the map. Alternatively, just about
any form of indirection in the comparator should work:

class X ;
class XCmp
{
public:
XCmp( X const* owner ) ;
bool operator()( int, int ) const ;

private:
X const* myOwner ;
} ;

class X
{
// ...
private:
std::map< int, int, XCmp >
myMap ;
} ;
The X objects
are a pain to construct (lots of big stuff in 'em) so I don't want to
generate them anymore than I have to.
Then you almost certainly don't want to use one directly as
comparator. The actual map uses a *copy* of the object it is
passed in the constructor (or a default constructed instance, if
it isn't passed a comparator).
I guess that second could be
made to work if the goodStuff would be static, but it ain't.
You could probably work out something using boost::bind. The
basic problem is that you have a function with three arguments
(the X and the two ints), and map will want to call it with two,
so you need to use a functional object which contains a pointer
to (or a reference to) the X. And you can't do it with the
standard binders, because the (current) version of the standard
doesn't support functional objects with more than two
parameters.
This isn't a stopper problem, I know a way around this
(problem- specific), but it stinks. I want to know how to do
this "the way it should be done".
"The way it should be done" probably depends on the context, but
most likely involves a comparator object with a pointer to (or a
reference to) the owning X.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jul 9 '07 #3
vulpes wrote:
This similar situation will explain somewhat, what I want to do:

class X {
public:
X() : map_(*this) {}

bool operator() (int a, int b) { return goodStuff(a) <
goodStuff(b); }
int goodStuff(int a) { ... }

private:
map<int, int, Xmap_;
};
#include <map>
using namespace std;

class X {
public:
X(){}

bool operator() (int a, int b) { return goodStuff(a) <
goodStuff(b); }
int goodStuff(int a) { return a; }
};

class Y
{
public:
Y():map_(x){}
private:
map<int, int, Xmap_;
X x;
};

int main()
{
Y x;
}

Is this good enough for your use?
Jul 9 '07 #4
On Jul 9, 1:06 pm, anon <a...@no.nowrote:
class X {
public:
X(){}

bool operator() (int a, int b) { return goodStuff(a) <
goodStuff(b); }
int goodStuff(int a) { return a; }
};

class Y
{
public:
Y() : map_(x){}

private:
map<int, int, Xmap_;
X x;
};

int main()
{
Y x;
}

Is this good enough for your use?
Well it's fine otherwise, but I'd rather let the class X be the main
character in the plot. Here's why: The class X is actually one of
several concretizations to an interface class and I use the class X
exclusively through that interface. It would be an unnecessary
complication to create a whole facade in front of X. Therefore I
wouldn't use your solution, it's like an inverse Adapter. But at least
there seems to be a slew of ways to do it, if you just keep pressing
the issue.

Thanks for your help. If you want, I'll post my final decision and
code here when I get to it (This evening European time I'd wager).
Someone may benefit from it later on.

Jul 9 '07 #5

anon <an**@no.nowrote in message...
>
What is ptr_fun?
Here is the same as the previous. You want to construct the map<int,int>
object from ptr_fun (whatever that is)
[ from STL docs ]

- Description -
Ptr_fun takes a function pointer as its argument and returns a function
pointer adaptor, a type of function object. It is actually two different
functions, not one (that is, the name ptr_fun is overloaded). If its
argument is of type Result (*)(Arg) then ptr_fun creates a
pointer_to_unary_function, and if its argument is of type Result (*)(Arg1,
Arg2) then ptr_fun creates a pointer_to_binary_function.

- Definition -
Defined in the standard header <functional>, and in the nonstandard
backward-compatibility header <function.h>.

--
Bob R
POVrookie
Jul 10 '07 #6

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

Similar topics

12
by: Olumide | last post by:
I'm studying Nigel Chapman's Late Night Guide to C++ which I think is an absolutely fantastic book; however on page 175 (topic: operator overlaoding), there the following code snippet: inline...
5
by: bipod.rafique | last post by:
Hello All, I am little confused about the constructor function. Say I have a class like the following class test{ int a; public: test(){}
2
by: Lateralus | last post by:
headers/vector3.h: In member function ‘Vector3 Vector3::operator*(Scalar)’: headers/vector3.h:13: error: no matching function for call to ‘Vector3::Vector3(Vector3)’...
6
by: Alexis Nikichine | last post by:
Hello, Today, I have a function: function f() { } and am looking for a way of distinguishing, from inside f, whether it
41
by: Telmo Costa | last post by:
Hi. I have the following code: -------------------------------------- function Tunnel() { //arguments(???); } function Sum() { var sum = 0; for (i=0; i<arguments.length; i++) sum +=...
17
by: Matt Kruse | last post by:
Perl's map() function is a powerful shortcut to accomplish many "loop over an array and do X" operations. Below is a quick hack to simulate similar functionality. I've used it a few times and find...
26
by: Patient Guy | last post by:
The code below shows the familiar way of restricting a function to be a method of a constructed object: function aConstructor(arg) { if (typeof(arg) == "undefined") return (null);...
28
by: Larax | last post by:
Best explanation of my question will be an example, look below at this simple function: function SetEventHandler(element) { // some operations on element element.onclick = function(event) {
5
by: Daz | last post by:
Hi everyone. My query is very straight forward (I think). What's the difference between someFunc.blah = function(){ ; } and
9
by: Morten Lemvigh | last post by:
Is it possible to pass a pointer to a constructor or a class definition as argument to a function? Maybe in a way similar to passing function pointers...? The function should construct a number...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

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.