
A co-worker mentioned an interesting issue. I thought some metaprogramming, or at least more advanced insight into STL, might apply here. Consider a class derived from an STL collection. It features a special find(x) function that works with his search criteria. It returns an iterator into the collection. There are two forms needed: iterator find(x); const_iterator find(x) const; and the annoying part is that they contain exactly the same code. The implementation uses the inherited iterators and collection features to do the finding. The larger question is, is there a better way to approach that? The immediate question is, my thought of using a template helper requires the return type to be determined based on the constness of the incoming parameter for the collection type. Is there a handy metafunction for that already in existance? --John -silly company footer automatically added, sorry. TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Le 11/05/2010 19:30, John Dlugosz wrote:
Consider a class derived from an STL collection.
You should never do that.
It features a special find(x) function that works with his search criteria. It returns an iterator into the collection. There are two forms needed: iterator find(x); const_iterator find(x) const; and the annoying part is that they contain exactly the same code. The implementation uses the inherited iterators and collection features to do the finding.
The larger question is, is there a better way to approach that?
Macros?

________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de Mathias Gaunard [mathias.gaunard@ens-lyon.org] Enviado el: martes, 11 de mayo de 2010 20:35 Para: boost-users@lists.boost.org Asunto: Re: [Boost-users] metafunction question
Le 11/05/2010 19:30, John Dlugosz wrote:
Consider a class derived from an STL collection.
You should never do that.
Why not, why never? My opinions on this issue at: http://bannalia.blogspot.com/2008/02/derivation-without-virtual-destructor.h... Joaquín M López Muñoz Telefónica, Investigación y Desarrollo

Le 11/05/2010 19:41, JOAQUIN M. LOPEZ MUÑOZ a écrit :
________________________________________ De: boost-users-bounces@lists.boost.org [boost-users-bounces@lists.boost.org] En nombre de Mathias Gaunard [mathias.gaunard@ens-lyon.org] Enviado el: martes, 11 de mayo de 2010 20:35 Para: boost-users@lists.boost.org Asunto: Re: [Boost-users] metafunction question
Le 11/05/2010 19:30, John Dlugosz wrote:
Consider a class derived from an STL collection.
You should never do that.
Why not, why never? My opinions on this issue at:
http://bannalia.blogspot.com/2008/02/derivation-without-virtual-destructor.h...
While there are technical reasons not to do so (absence of virtual destructor), there are also non technical ones. It simply doesn't make sense to use inheritance for this. Inheritance is for polymorphism, not code reuse. This is why for example free functions that take any range are better than member functions.

While there are technical reasons not to do so (absence of virtual destructor), there are also non technical ones.
It simply doesn't make sense to use inheritance for this. Inheritance is for polymorphism, not code reuse.
This is why for example free functions that take any range are better than member functions.
So, you would prefer to use a generic programming model rather than member-function calling syntax? Do you write your classes to have only private virtual member functions, and declare non-member friend functions that take an instance as one of the parameters and call the virtual functions? No public members at all! If I have public member functions, and I want to extend that, it would be annoying to say "these 20 functions are members, and here is 1 more that is a non-member". TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Zitat von John Dlugosz
While there are technical reasons not to do so (absence of virtual destructor), there are also non technical ones.
It simply doesn't make sense to use inheritance for this. Inheritance is for polymorphism, not code reuse.
This is why for example free functions that take any range are better than member functions.
So, you would prefer to use a generic programming model rather than member-function calling syntax? Do you write your classes to have only private virtual member functions, and declare non-member friend functions that take an instance as one of the parameters and call the virtual functions? No public members at all!
If I have public member functions, and I want to extend that, it would be annoying to say "these 20 functions are members, and here is 1 more that is a non-member".
is your function an algorithm working WITH the container, or is it a function providing access to the container's contents? when you derive from a standard container without any additional state, it's most likely the former. for example, there is no std::vector::sort(), only std::sort(vector...) (although it seems to me the standard library doesn't draw a clear line there either. a lot of the member functions of std::string should have been free function algorithms)

is your function an algorithm working WITH the container, or is it a function providing access to the container's contents? when you derive from a standard container without any additional state, it's most likely the former. for example, there is no std::vector::sort(), only std::sort(vector...) (although it seems to me the standard library doesn't draw a clear line there either. a lot of the member functions of std::string should have been free function algorithms)
And, container-specific versions of algorithms are available as member functions, rather than just automatically picking up container-specific form based on the iterator. The reason for that is because the iterators in general don't reference back to the original container. But, with overloading, should there be a container-based find as well as iterator find algorithms, as opposed to find being a member? His example is called "find", so probably is a member because the plain find functions are also members of various containers. If the std::find was an overloaded non-member, he might "naturally" write his that way too. --John TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Why should he not derive from a standard collection?
-----Original Message----- From: boost-users-bounces@lists.boost.org [mailto:boost-users- bounces@lists.boost.org] On Behalf Of Mathias Gaunard Sent: Tuesday, May 11, 2010 1:35 PM To: boost-users@lists.boost.org Subject: Re: [Boost-users] metafunction question
Le 11/05/2010 19:30, John Dlugosz wrote:
Consider a class derived from an STL collection.
You should never do that.
TradeStation Group, Inc. is a publicly-traded holding company (NASDAQ GS: TRAD) of three operating subsidiaries, TradeStation Securities, Inc. (Member NYSE, FINRA, SIPC and NFA), TradeStation Technologies, Inc., a trading software and subscription company, and TradeStation Europe Limited, a United Kingdom, FSA-authorized introducing brokerage firm. None of these companies provides trading or investment advice, recommendations or endorsements of any kind. The information transmitted is intended only for the person or entity to which it is addressed and may contain confidential and/or privileged material. Any review, retransmission, dissemination or other use of, or taking of any action in reliance upon, this information by persons or entities other than the intended recipient is prohibited. If you received this in error, please contact the sender and delete the material from any computer.

Zitat von John Dlugosz
A co-worker mentioned an interesting issue. I thought some metaprogramming, or at least more advanced insight into STL, might apply here.
Consider a class derived from an STL collection. It features a special find(x) function that works with his search criteria. It returns an iterator into the collection. There are two forms needed: iterator find(x); const_iterator find(x) const; and the annoying part is that they contain exactly the same code. The implementation uses the inherited iterators and collection features to do the finding.
The larger question is, is there a better way to approach that?
The immediate question is, my thought of using a template helper requires the return type to be determined based on the constness of the incoming parameter for the collection type.
the return type cannot be parametrized based on the const-ness of "this". but parametrizing _functions_ based on constness rarely makes sense anyway, the best aproach imho is to keep the overloads but let them only handle the const/non-const specific stuff and forward the rest. in your example: private: node_ptr find_node(x) const; public: iterator find(x){ return iterator(find_node(x)); } const_iterator find(x) const{ return const_iterator(find_node(x)); }

the return type cannot be parametrized based on the const-ness of "this". but parametrizing _functions_ based on constness rarely makes sense anyway, the best aproach imho is to keep the overloads but let them only handle the const/non-const specific stuff and forward the rest. in your example:
private: node_ptr find_node(x) const; public: iterator find(x){ return iterator(find_node(x)); } const_iterator find(x) const{ return const_iterator(find_node(x)); }
That was exactly what I showed him. And that would work for "contained" stuff that was not contained by value. But, the find_node works using the inherited iterators, not his own mechanisms. So, the private iterator do_find(x) const finds itself limited to const_iterator in its own implementation from the getgo.
I was thinking
template

On May 11, 11:30 am, John Dlugosz
A co-worker mentioned an interesting issue. I thought some metaprogramming, or at least more advanced insight into STL, might apply here.
Consider a class derived from an STL collection. It features a special find(x) function that works with his search criteria. It returns an iterator into the collection. There are two forms needed: iterator find(x); const_iterator find(x) const; and the annoying part is that they contain exactly the same code. The implementation uses the inherited iterators and collection features to do the finding.
Not sure about the details but if the code is repeated in a const and a non const function then just write one of them (e.g. the const version) and make one call the other, take care of constness removal/ added with const_cast. As long as you know what you are doing there is no harm in doing cast, that's why they are there in the first place. Enjoy life/C++ (please, no c++ tele-evangelist saying "don't do that!, sinner") Alfredo
participants (6)
-
alfC
-
JOAQUIN M. LOPEZ MUÑOZ
-
John Dlugosz
-
Mathias Gaunard
-
Mathieu -
-
strasser@uni-bremen.de