c++ problem with temporany reference

A

alessio211734

Hello,

I have the following problem. I have this method:

void holeFilling::updateNearFaces( tri::Allocator<CMeshO>::pointerUpdater<CMeshO::FacePointer> pu, std::set<CMeshO::FacePointer> & faces )
{
std::set<CMeshO::FacePointer>::iterator it;
for (it=faces.begin();it!=faces.end();++it)
{
//CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update((*it));
}
}

where the function Update is defined as:

template<class SimplexPointerType>
class PointerUpdater
{
void Update(SimplexPointerType &vp)
{
//if(vp>=newBase && vp<newEnd) return;
if(vp<oldBase || vp>oldEnd) return;
assert(vp>=oldBase);
assert(vp<oldEnd);
vp=newBase+(vp-oldBase);
if(!remap.empty())
vp = newBase + remap[vp-newBase];
}

with the microsoft compiler with no problem while with mingw I get an error.
....holeFilling.cpp:1471: error: no matching function for call to 'vcg::tri::Allocator<CMeshO>::pointerUpdater<CFaceO*>::Update(CFaceO* const&)'
if (pu.NeedUpdate()) pu.Update((*it));
^
if I replace the code so:

CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update(fp);
compile on mingw but its different because I need to change the pointer (*it).

Thanks in advance.


Ale.
 
A

Alf P. Steinbach

Hello,

I have the following problem. I have this method:

void holeFilling::updateNearFaces( tri::Allocator<CMeshO>::pointerUpdater<CMeshO::FacePointer> pu, std::set<CMeshO::FacePointer> & faces )
{
std::set<CMeshO::FacePointer>::iterator it;
for (it=faces.begin();it!=faces.end();++it)
{
//CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update((*it));
}
}

where the function Update is defined as:

template<class SimplexPointerType>
class PointerUpdater
{
void Update(SimplexPointerType &vp)
{
//if(vp>=newBase && vp<newEnd) return;
if(vp<oldBase || vp>oldEnd) return;
assert(vp>=oldBase);
assert(vp<oldEnd);
vp=newBase+(vp-oldBase);
if(!remap.empty())
vp = newBase + remap[vp-newBase];
}

with the microsoft compiler with no problem while with mingw I get an error.
...holeFilling.cpp:1471: error: no matching function for call to 'vcg::tri::Allocator<CMeshO>::pointerUpdater<CFaceO*>::Update(CFaceO* const&)'
if (pu.NeedUpdate()) pu.Update((*it));
^
if I replace the code so:

CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update(fp);
compile on mingw but its different because I need to change the pointer (*it).

You can't change the stored member of a std::set, because that can
change whether it is logically a member, without the set's knowledge.

A std::set guarantees that its values are unique. After a change, if
that were allowed, the values might not be unique.

One way to resolve this: you can remove the value from the set, and add
the new value to the set.

Another way to resolve it: use a different data structure, one that
permits duplicates, such as std::vector.

How reasonable any solution is depends on your purpose with this, but
just to recap the problem: a set offers a uniqueness guarantee that
could easily be broken if you could just arbitrary modify set elements.


Cheers & hth.,

- Alf
 
V

Victor Bazarov

I have the following problem. I have this method:

void holeFilling::updateNearFaces( tri::Allocator<CMeshO>::pointerUpdater<CMeshO::FacePointer> pu, std::set<CMeshO::FacePointer> & faces )
{
std::set<CMeshO::FacePointer>::iterator it;
for (it=faces.begin();it!=faces.end();++it)
{
//CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update((*it));
}
}

where the function Update is defined as:

template<class SimplexPointerType>
class PointerUpdater
{
void Update(SimplexPointerType &vp)
{
//if(vp>=newBase && vp<newEnd) return;
if(vp<oldBase || vp>oldEnd) return;
assert(vp>=oldBase);
assert(vp<oldEnd);
vp=newBase+(vp-oldBase);
if(!remap.empty())
vp = newBase + remap[vp-newBase];
}

with the microsoft compiler with no problem while with mingw I get an error.
...holeFilling.cpp:1471: error: no matching function for call to 'vcg::tri::Allocator<CMeshO>::pointerUpdater<CFaceO*>::Update(CFaceO* const&)'
if (pu.NeedUpdate()) pu.Update((*it));
^
if I replace the code so:

CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update(fp);
compile on mingw but its different because I need to change the pointer (*it).

Your problem is that you're trying to update the value in 'std::set' in
place. It is not allowed. The set keeps its values sorted, so a change
in any value can disrupt the sorting. What you need to do is to
determine the new value and re-insert it into the set after removing the
one that doesn't need to be there anymore.

Technically, the set iterator returns a reference to a const value when
you dereference it. Microsoft cuts some corners (disable language
extensions to prohibit it from cutting corners), and that's why it
appears to work. In fact, your code has undefined behavior.

Change your loop
for (it=faces.begin();it!=faces.end();++it)
{
//CMeshO::FacePointer fp=(*it);
if (pu.NeedUpdate()) pu.Update((*it));
}


to something like this

if (pu.NeedUpdate())
{
std::vector<CMeshO::FacePointer> updated;
for (it = faces.begin(); it != faces.end();) // note no ++it
{
CMeshO::FacePointer fp = *it;
pu.Update(fp);
updated.push_back(fp);
it = faces.erase(it); // this is where 'it' changes
}
for (int i = 0; i < updated.size(); ++i)
faces.insert(updated);
}

V
 
A

alessio211734

You can't change the stored member of a std::set, because that can
change whether it is logically a member, without the set's knowledge.



A std::set guarantees that its values are unique. After a change, if

that were allowed, the values might not be unique.

thanks very much!
 
A

Anand Hariharan

)
with the microsoft compiler with no problem while with mingw I get an error.


Alf and Victor have resolved your problem; just wanted to add that a reasonably new compiler from Microsoft (VS 2010 and later) would reject that code.

- Anand
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top