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

pointer-to-member of pair<>

Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){
if (global == 0){
myObj = it->func().second->anObj();
} else {
myObj = it->func().first->anObj();
}
myVec.push_back(anObj);
}

where it->func() returns a pair of objects' pointers with 'anObj' functions which return an object
suitable for insertion in myVec.

Now, given that 'global' is known before I enter any loops, I could in principle decide to use the
'first' or 'second' before I ever enter this loop, instead of deciding inside the loop (and
hopefully thus save a few ns of time)... I thought to use a pointer-to-member (the member being
'first' or 'second') but cannot figure out the syntax.
This is what I am trying:

const primaryObj * pair<const primaryObj *, const primaryObj *>::*pFirstOrSecond;
pFirstOrSecond = global? (&pair<const primaryObj *,const primaryObj *>::first):(pair<const
primaryObj *,const primaryObj *>::second);

the compiler complains :

.../src/SCTHitsNoiseMonTool.cxx: In member function `StatusCode
SCTHitsNoiseMonTool::generalHistsandNoise()':
/usr/lib/gcc/x86_64-redhat-linux/3.4.6/../../../../include/c++/3.4.6/bits/stl_pair.h:74: error:
object missing in reference to `std::pair<const Trk::PrepRawData*, const Trk::PrepRawData*>::second'

where Trk::PrepRawData corresponds to 'primaryObj' in the example above, as if it is looking for the
concrete object rather than the generic pointer-to-member.

can anyone help?

cheers
shaun
Jun 27 '08 #1
9 3696
On 11 Jun, 11:32, shaun roe <shaun....@wanadoo.frwrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){
* if (global == 0){
* * myObj = it->func().second->anObj();
* } else {
* * myObj = it->func().first->anObj();
* }
* myVec.push_back(anObj);

}

where it->func() returns a pair of objects' pointers with 'anObj' functions which return an object
suitable for insertion in myVec.

Now, given that 'global' is known before I enter any loops, I could in principle decide to use the
'first' or 'second' before I ever enter this loop, instead of deciding inside the loop (and
hopefully thus save a few ns of time)... I thought to use a pointer-to-member (the member being
'first' or 'second') but cannot figure out the syntax.
This is what I am trying:

*const primaryObj * pair<const primaryObj *, const primaryObj *>::*pFirstOrSecond;
* *pFirstOrSecond = global? (&pair<const primaryObj *,const primaryObj *>::first):(pair<const
primaryObj *,const primaryObj *>::second);

the compiler complains :
[snip]
can anyone help?
I think I understand what you are trying to do, but I don't think it's
possible, because there is no special "pointer to data-member".

Such a pointer would on most implementations be equivalent to the byte
offset from the beginning of the object's data structure to the data
member, IOW very similar to the "offsetof" macro.

However, you can't (formally) use offsetof on a pair, because it is
not strictly POD (it has a user-declared ctor). It would still
probably work on most implementations.

Other options include writing the loop twice:
if(global == 0)
// entire loop
else
// entire loop

Or rewrite the loop using functors to fetch the object, something like
this:

if(global == 0)
std::transform(vec.begin(), vec.end(), std::back_inserter(myVec),
get1st());
else
std::transform(vec.begin(), vec.end(), std::back_inserter(myVec),
get2nd());

Which may or may not be faster than the original loop ;)

DP
Jun 27 '08 #2
On Jun 11, 5:32*am, shaun roe <shaun....@wanadoo.frwrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){
* if (global == 0){
* * myObj = it->func().second->anObj();
* } else {
* * myObj = it->func().first->anObj();
* }
* myVec.push_back(anObj);

}
can anyone help?
I think you are heading into Knuthian territory here, but, perhaps you
could add:
it->funcFirst() and it->funcSecond()

Then outside the loop create a pointer to one or the other of these
functions (since I presume they have the same signature).

Then you _could_ use this pointer to member function inside the loop.

Joe Cook
Jun 27 '08 #3
shaun roe wrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){
Huh? Could it be that you are trying to do the job of the compilers
optimizing pass?
if (global == 0){
myObj = it->func().second->anObj();
} else {
myObj = it->func().first->anObj();
}
myVec.push_back(anObj);
}

where it->func() returns a pair of objects' pointers with 'anObj'
functions which return an object suitable for insertion in myVec.

Now, given that 'global' is known before I enter any loops, I could in
principle decide to use the 'first' or 'second' before I ever enter this
loop, instead of deciding inside the loop (and hopefully thus save a few
ns of time)...
So what is wrong with

if ( global == 0 ) {
// use second fields
for(it(vec.begin(), end(vec.end()), it!=end;++it){
myVec.push_back( it->func().second->anObj() );
}
else {
// use first fields
for(it(vec.begin(), end(vec.end()), it!=end;++it){
myVec.push_back( it->func().first->anObj() );
}
}
[snip]
Best

Kai-Uwe Bux
Jun 27 '08 #4
In article
<d7**********************************@d77g2000hsb. googlegroups.com>,
Triple-DES <De**********@gmail.comwrote:
On 11 Jun, 11:32, shaun roe <shaun....@wanadoo.frwrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){
* if (global == 0){
* * myObj = it->func().second->anObj();
* } else {
* * myObj = it->func().first->anObj();
* }
* myVec.push_back(anObj);

}
[snip]
>
I think I understand what you are trying to do, but I don't think it's
possible, because there is no special "pointer to data-member".
ok, thanks... I'm using 'C++ Common Knowledge',S. C. Dewhurst, Item 15
:Pointers to Class Members Are Not Pointers
as a reference, where I see:
class C{
public:
int a_;
};
intC::*pimC;
C aC;
C *pC = &aC;
aC.*pimC=0;
int b=pC->*pimC;

so I was hoping to do the same for a pair; however If I understand your
comment below, this is not possible where there is a non-trivial
constructor...this is an important caveat!

cheers
s
>
Such a pointer would on most implementations be equivalent to the byte
offset from the beginning of the object's data structure to the data
member, IOW very similar to the "offsetof" macro.

However, you can't (formally) use offsetof on a pair, because it is
not strictly POD (it has a user-declared ctor). It would still
probably work on most implementations.

Other options include writing the loop twice:
if(global == 0)
// entire loop
else
// entire loop

Or rewrite the loop using functors to fetch the object, something like
this:

if(global == 0)
std::transform(vec.begin(), vec.end(), std::back_inserter(myVec),
get1st());
else
std::transform(vec.begin(), vec.end(), std::back_inserter(myVec),
get2nd());

Which may or may not be faster than the original loop ;)

DP
Jun 27 '08 #5
shaun roe wrote:
In article
<d7**********************************@d77g2000hsb. googlegroups.com>,
Triple-DES <De**********@gmail.comwrote:
>On 11 Jun, 11:32, shaun roe <shaun....@wanadoo.frwrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like
this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){
if (global == 0){
myObj = it->func().second->anObj();
} else {
myObj = it->func().first->anObj();
}
myVec.push_back(anObj);

}
[snip]
>>
I think I understand what you are trying to do, but I don't think it's
possible, because there is no special "pointer to data-member".

ok, thanks... I'm using 'C++ Common Knowledge',S. C. Dewhurst, Item 15
:Pointers to Class Members Are Not Pointers
as a reference, where I see:
class C{
public:
int a_;
};
intC::*pimC;
C aC;
C *pC = &aC;
aC.*pimC=0;
int b=pC->*pimC;
What's stopping you?

#include <utility>
#include <iostream>

typedef std::pair<int,intint_pair;
typedef int int_pair::* int_member_ptr;

int main ( void ) {
int_member_ptr ptr1 = &int_pair::first;
int_member_ptr ptr2 = &int_pair::second;
int_pair the_pair ( 2, 3 );
std::cout << the_pair.*ptr1 << '\n';
std::cout << the_pair.*ptr2 << '\n';
}

so I was hoping to do the same for a pair; however If I understand your
comment below, this is not possible where there is a non-trivial
constructor...this is an important caveat!
Huh?

The real problem is that for pair<T,S>, this will not work since the pointer
has to point to T or to S. Thus, stuff like this can only be done for
a "diagonal" pair<T,T>.

Best

Kai-Uwe Bux
Jun 27 '08 #6
In article <g2**********@aioe.org>, Kai-Uwe Bux <jk********@gmx.net>
wrote:
[snip]
>
}

so I was hoping to do the same for a pair; however If I understand your
comment below, this is not possible where there is a non-trivial
constructor...this is an important caveat!

Huh?

The real problem is that for pair<T,S>, this will not work since the pointer
has to point to T or to S. Thus, stuff like this can only be done for
a "diagonal" pair<T,T>.

Best

Kai-Uwe Bux
Indeed I have a 'diagonal' pair, the only structural difference is that
they are const pointers, so I must be awry somewhere in my syntax...
I'll try harder with a simpler example and come back if that doesnt work!

thanks

shaun
Jun 27 '08 #7
On 11 Jun, 23:03, shaun roe <shaun....@wanadoo.frwrote:
*Triple-DES <DenPlettf...@gmail.comwrote:
I think I understand what you are trying to do, but I don't think it's
possible, because there is no special "pointer to data-member".
From your citation, it is obvious that this is just plain wrong. At
least my description of its implementation is fairly accurate.

[snip]
so I was hoping to do the same for a pair; however If I understand your
comment below, this is not possible where there is a non-trivial
constructor...this is an important caveat!
Yes, this is true for the offsetof macro. It is however not true for
pointers to class members (see Kai-Uwe's post). Note that I still
think using std::transform is the most elegant way of accomplishing
your task :)

DP
Jun 27 '08 #8
"Kai-Uwe Bux" <jk********@gmx.netwrote
shaun roe wrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){

Huh? Could it be that you are trying to do the job of the compilers
optimizing pass?
if (global == 0){
myObj = it->func().second->anObj();
} else {
myObj = it->func().first->anObj();
}
myVec.push_back(anObj);
}

where it->func() returns a pair of objects' pointers with 'anObj'
functions which return an object suitable for insertion in myVec.

Now, given that 'global' is known before I enter any loops, I could in
principle decide to use the 'first' or 'second' before I ever enter this
loop, instead of deciding inside the loop (and hopefully thus save a few
ns of time)...

So what is wrong with

if ( global == 0 ) {
// use second fields
for(it(vec.begin(), end(vec.end()), it!=end;++it){
myVec.push_back( it->func().second->anObj() );
}
else {
// use first fields
for(it(vec.begin(), end(vec.end()), it!=end;++it){
myVec.push_back( it->func().first->anObj() );
}
}
I'd do it as follows:

for(it(vec.begin(), end(vec.end()), it!=end;++it)
myVec.push_back(!global ? it->func().second->anObj() : it->func().first->anObj());
Jun 27 '08 #9
Adem24 wrote:
"Kai-Uwe Bux" <jk********@gmx.netwrote
>shaun roe wrote:
Question about pointer-to-data members

I have a deeply nested loop, the innermost bit looks a little like
this:

for(it(vec.begin(), end(vec.end()), it!=end;++it){

Huh? Could it be that you are trying to do the job of the compilers
optimizing pass?
if (global == 0){
myObj = it->func().second->anObj();
} else {
myObj = it->func().first->anObj();
}
myVec.push_back(anObj);
}

where it->func() returns a pair of objects' pointers with 'anObj'
functions which return an object suitable for insertion in myVec.

Now, given that 'global' is known before I enter any loops, I could in
principle decide to use the 'first' or 'second' before I ever enter
this loop, instead of deciding inside the loop (and hopefully thus save
a few ns of time)...

So what is wrong with

if ( global == 0 ) {
// use second fields
for(it(vec.begin(), end(vec.end()), it!=end;++it){
myVec.push_back( it->func().second->anObj() );
}
else {
// use first fields
for(it(vec.begin(), end(vec.end()), it!=end;++it){
myVec.push_back( it->func().first->anObj() );
}
}

I'd do it as follows:

for(it(vec.begin(), end(vec.end()), it!=end;++it)
myVec.push_back(!global ? it->func().second->anObj() :
it->func().first->anObj());
You don't like white space, do you?

Note that the OP specifically intended to pull the check for global out of
the loop (you even quoted that):
Now, given that 'global' is known before I enter any loops, I could in
principle decide to use the 'first' or 'second' before I ever enter
this loop, instead of deciding inside the loop (and hopefully thus save
a few ns of time)...

Best

Kai-Uwe Bux
Jun 27 '08 #10

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

Similar topics

11
by: Jamie Burns | last post by:
Hello, I just did a simple benchmark: for (xx=0;xx<100000;xx++) { rDerived* derived = dynamic_cast<rDerived*>(object); if (derived) derived->setValue(message.data.messageSetInt.value); } ...
10
by: dalbosco | last post by:
Hello, I am new to STL and I've written the following code which crash. Could anyone tell me why this code crash? Thanks by advance. -- J-F #include <iostream>
6
by: Roman Töngi | last post by:
I want to change a vector in a function. I pass a pointer of it to the function and append an item. Then I want to print the first item in the vector. It doesn't work. Can anyone help me? Thanks...
23
by: Helge Moulding | last post by:
I've tried the following: <a name="foo" class="foostyle">Text in foo <a href="bar">link in foo</a> and more text.</a> I kinda thought that oughta work. But I found that foostyle is applied...
10
by: Eric-Sebastien Lachance | last post by:
Hey there, I decided to just create a 100% height and width div that filled the space over a background header image, and add an onclick event to redirect to the my index... Doesn't seem to work...
3
by: Franck | last post by:
Hello, in a datagrid, in the ItemDataBound event in some cells a add some javascript that show up an information strHref.Append("<A onclick=\"popupValid();\">"); strHref.Append("<span...
5
by: mkaushik | last post by:
Hi everyone, Im just starting out with C++, and am curious to know how "delete <pointer>", knows about the number of memory locations to free. I read somewhere that delete frees up space...
27
by: Noah Roberts | last post by:
What steps do people take to make sure that when dealing with C API callback functions that you do the appropriate reinterpret_cast<>? For instance, today I ran into a situation in which the wrong...
1
by: Peter Lee | last post by:
store std::<map>::iterator is safe if didn't remove that element Is store std::<mapelement's pointer also safe ?
6
by: JackC | last post by:
Hi, If i have a vector<charmaybe 15mb in size, whats the most efficient way to write out all the elements to an output file? I have tried this: for(int z = 0; z < Output_Buffer.size(); z++)...
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
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?
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...
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
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
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.