B
benben
I have always found Stroustrup's paper on generalized member function
wrapper (http://www.research.att.com/~bs/wrapper.pdf) an interesting
one. Recently I started to play with it. As I tried to put some extra
data members (such as a std::vector) to the Call_proxy<> class template
it started to worry me because if the suffix in the destructor throws,
there can be a memory leak. (See relevant code below)
The Call_proxy<> uses its own destructor to facilitate a call to a
suffix at the end of a statement (as an instance of Call_proxy<> is
always a temporary.) This isn't a problem in the proposal in the paper
because the original version of the class template has no data member
that requires non-trivial destruction.
I am wondering if anyone has an idea as to how to improve the exception
safety. The requirements are:
1. If suffix() call throws, data members in Call_proxy<> are properly
destroyed.
2. The exception thrown is to be catched by the caller (i.e. the
destructor must be allowed to throw.
RELEVANT CODE
/***********************************************
Quoted from
http://www.research.att.com/~bs/wrapper.pdf
pp5.
Changes applied and commented
************************************************/
template <class T> class Wrap;
template <class T>
class Call_proxy{
T* p;
mutable bool own;
Call_proxy(T* pp)(pp), own(true){}
Call_proxy(const Call_proxy& a): p(a.p), own(true){a.own = false;}
Call_proxy& operator=(const Call_proxy&);
std::vector<int> extra; // extra data member (added by me)
public:
template <class U> friend class Wrap;
~Call_proxy()
{
if(own) suffix(); // if this throws, extra will leak
}
T* operator->()const{return p;}
};
END OF RELEVANT CODE
My current work around is to do a vector swap trick
~Call_proxy()
{
std::vector<int> temp;
temp.swap(extra);
if (own) suffix(); // if throws temp will
// be destructed
// properly
}
But this is cumbersome and hardly general.
Regards,
Ben
wrapper (http://www.research.att.com/~bs/wrapper.pdf) an interesting
one. Recently I started to play with it. As I tried to put some extra
data members (such as a std::vector) to the Call_proxy<> class template
it started to worry me because if the suffix in the destructor throws,
there can be a memory leak. (See relevant code below)
The Call_proxy<> uses its own destructor to facilitate a call to a
suffix at the end of a statement (as an instance of Call_proxy<> is
always a temporary.) This isn't a problem in the proposal in the paper
because the original version of the class template has no data member
that requires non-trivial destruction.
I am wondering if anyone has an idea as to how to improve the exception
safety. The requirements are:
1. If suffix() call throws, data members in Call_proxy<> are properly
destroyed.
2. The exception thrown is to be catched by the caller (i.e. the
destructor must be allowed to throw.
RELEVANT CODE
/***********************************************
Quoted from
http://www.research.att.com/~bs/wrapper.pdf
pp5.
Changes applied and commented
************************************************/
template <class T> class Wrap;
template <class T>
class Call_proxy{
T* p;
mutable bool own;
Call_proxy(T* pp)(pp), own(true){}
Call_proxy(const Call_proxy& a): p(a.p), own(true){a.own = false;}
Call_proxy& operator=(const Call_proxy&);
std::vector<int> extra; // extra data member (added by me)
public:
template <class U> friend class Wrap;
~Call_proxy()
{
if(own) suffix(); // if this throws, extra will leak
}
T* operator->()const{return p;}
};
END OF RELEVANT CODE
My current work around is to do a vector swap trick
~Call_proxy()
{
std::vector<int> temp;
temp.swap(extra);
if (own) suffix(); // if throws temp will
// be destructed
// properly
}
But this is cumbersome and hardly general.
Regards,
Ben