[Range] Extending the library for a base class and all its derived - enable_if
Hello, I am looking to make a class, whose definition I cannot touch, model a Range concept. To that end I use method 2, http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/ext... However, I am unable to specialize the relevant metafunctions (range_const_iterator, range_mutable_iterator, range_iterator) since they do not have an additional template parameter that would permit me to employ enable_if. I have found this impossible without touching either the class' definition or the metafunctions. Perhaps there is some other trick I am not aware of, in which case I would greatly appreciate hearing about it. If such a trick does not exist, then should these metafunctions feature an additional template parameter? Given that this is one of the methods to extend the library, it would make sense that one wishes to do so on conditions that enable_if can check. Albert
On Wed, Apr 23, 2014 at 2:13 PM, Albert Yiamakis
Hello,
I am looking to make a class, whose definition I cannot touch, model a Range concept. To that end I use method 2,
http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/ext...
However, I am unable to specialize the relevant metafunctions (range_const_iterator, range_mutable_iterator, range_iterator) since they do not have an additional template parameter that would permit me to employ enable_if.
Generally it isn't necessary to use enable_if to achieve this. There support for MFC containers was added by using method 2 to non-intrusively add support.
I have found this impossible without touching either the class' definition or the metafunctions. Perhaps there is some other trick I am not aware of, in which case I would greatly appreciate hearing about it.
I'm not sure if there is something special about your use-case that stops method 2 from working. Perhaps you could take a look at the MFC support in Boost.Range to see if this helps you add support for your classes. If you can provide some code that shows the classes you are trying to make support ranges then I'd be happy to try and help.
If such a trick does not exist, then should these metafunctions feature an additional template parameter? Given that this is one of the methods to extend the library, it would make sense that one wishes to do so on conditions that enable_if can check.
So far I have never needed an additional parameter. I suspect that we don't need the additional parameter, but I'm willing to look at new use cases and make appropriate changes if they are warranted.
Albert
Regards, Neil Groves
On 23/04/14 16:28, Neil Groves wrote:
On Wed, Apr 23, 2014 at 2:13 PM, Albert Yiamakis
wrote: Hello,
I am looking to make a class, whose definition I cannot touch, model a Range concept. To that end I use method 2,
http://www.boost.org/doc/libs/1_55_0/libs/range/doc/html/range/reference/ext...
However, I am unable to specialize the relevant metafunctions (range_const_iterator, range_mutable_iterator, range_iterator) since they do not have an additional template parameter that would permit me to employ enable_if.
Generally it isn't necessary to use enable_if to achieve this. There support for MFC containers was added by using method 2 to non-intrusively add support.
My statement isn't correct - what I really mean is: I am unable to specialize the relevant metafunctions *for the derived types of the class*. Of course specializing them for a single class is not an issue.
I'm not sure if there is something special about your use-case that stops method 2 from working. Perhaps you could take a look at the MFC support in Boost.Range to see if this helps you add support for your classes.
If you can provide some code that shows the classes you are trying to make support ranges then I'd be happy to try and help.
A simple example:
class Base {/* stuff */}; //it is in fact an abstract base class but
shouldn't matter
class Iterator {/* stuff */ }; //will be used to iterate - assume the
default constructed represents end
Now I 'd like all classes that derive from Base to model a Range. I have
only been able to do this by adding the additional template parameter
myself, then this is possible:
namespace boost
{
template <typename C>
struct range_iterator
::type> { typedef Iterator type; }; }
(Also the following is already possible, without the hack):
template <typename T>
Iterator range_begin(T& foo, typename
boost::enable_if
So far I have never needed an additional parameter. I suspect that we don't need the additional parameter, but I'm willing to look at new use cases and make appropriate changes if they are warranted.
I could also imagine that the user may wish to use a trait other than is_base_of to decide whether a class should model a range (but I do not have a concrete example in mind). Albert
On 04/23/2014 06:51 PM, Albert Yiamakis wrote:
I'm not sure if there is something special about your use-case that stops method 2 from working. Perhaps you could take a look at the MFC support in Boost.Range to see if this helps you add support for your classes.
If you can provide some code that shows the classes you are trying to make support ranges then I'd be happy to try and help.
A simple example:
class Base {/* stuff */}; //it is in fact an abstract base class but shouldn't matter
class Iterator {/* stuff */ }; //will be used to iterate - assume the default constructed represents end
Now I 'd like all classes that derive from Base to model a Range. I have only been able to do this by adding the additional template parameter myself, then this is possible:
namespace boost {
template <typename C> struct range_iterator
>::type> { typedef Iterator type; }; template<typename C> struct range_const_iterator
::type> { typedef Iterator type; }; }
Would something like
template <typename C>
struct range_iterator
On 04/25/2014 04:19 AM, Albert Yiamakis wrote:
On 24/04/14 15:00, Avi Kivity wrote:
Would something like
template <typename C> struct range_iterator
, C>::type> { ... }; work? This does not compile.
Well, it should be
template <typename C>
struct range_iterator
On 25/04/14 12:54, Avi Kivity wrote:
template <typename C> struct range_iterator
::value, C>::type> { ... };
Boost's enable_if has no value member, you are thinking of the STL one introduced in C++11.
but an simpler example I tried also does not compile, complaining that template parameter C is not used (though it clearly is). I wonder if it's a bug in the error message (and the code is disallowed) or a real compiler bug.
Are you conjecturing wildly here? There is nothing unusual about the error message. The documentation for enable_if is quite clear - an additional template parameter is needed.
Would something like
template <typename C> struct range_iterator
, C>::type> { ... }; work? This does not compile.
Well, it should be
template <typename C> struct range_iterator
::value, C>::type> { ... }; but an simpler example I tried also does not compile, complaining that template parameter C is not used (though it clearly is). I wonder if it's a bug in the error message (and the code is disallowed) or a real compiler bug.
The code is disallowed. In order to select the partial specialization
for some argument type 'A', the compiler would have to compare 'A' and
'typename enable_if
On 04/26/2014 07:05 AM, Nathan Ridge wrote:
Would something like
template <typename C> struct range_iterator
, C>::type> { ... }; work? This does not compile.
Well, it should be
template <typename C> struct range_iterator
::value, C>::type> { ... }; but an simpler example I tried also does not compile, complaining that template parameter C is not used (though it clearly is). I wonder if it's a bug in the error message (and the code is disallowed) or a real compiler bug. The code is disallowed. In order to select the partial specialization for some argument type 'A', the compiler would have to compare 'A' and 'typename enable_if
::value, C>::type' and deduce 'C'. It cannot do this (in standardese this is called a "non-deduced context").
Ok, thanks for the clarification.
participants (4)
-
Albert Yiamakis
-
Avi Kivity
-
Nathan Ridge
-
Neil Groves