Does it still fail even if you don't use BOOST_CONCEPT_REQUIRES? If the function fails only with a void return type, are you sure you're not trying to return something (at least along some control flow path)? What in particular is the error message you get?On Tue, 27 Mar 2012, Robert Jones wrote:
On Tue, Mar 27, 2012 at 5:02 PM, Jeremiah Willcock <jewi...@osl.iu.edu> wrote:
On Tue, 27 Mar 2012, Robert Jones wrote:
Hi Peeps
Can anyone cast any light on this...
I want to write function which accepts a single pass range of X's, so something like this
struct X { };
template <typename T>
BOOST_CONCEPT_REQUIRES(
(( boost::SinglePassRangeConcept<T> )),
( typename boost::enable_if<boost::is_same<typename boost::range_value<T>::type, X>, void>::type ))
my_function( const T & range );
Is that a reasonable construction, or is there a better way to say it?
Next, it doesn't seem to work. It does seem to work if the type to which enable_if resolves is anything
except void, but not for void. Why is this?
Does it only fail if you try to pass something in that is not a range? I'm not sure that BOOST_CONCEPT_REQUIRES does SFINAE, but if it does, you will need a
metafunction (and possibly lazy_enable_if) to avoid accessing range_value<T> when T is not a range if that doesn't instantiate properly for non-ranges.
No, it fails when the parameter IS a valid range, of the required value type. I can create the same effect by
substituting void for the whole enable_if bit, and then using BOOST_ASSERT in the body of the function to impose
the same condition, but that is obviously less satisfactory.
I suspect void is special because it is enable_if's returned type if type is not specified, but I can't quite see why, or
what the impact of that is.
> Hi All
>
> Ok, I should probably have started this thread with this self contained code example.
>
> What's wrong with this?
>
>
> #include <vector>
> #include <boost/concept/requires.hpp>
> #include <boost/range/concepts.hpp>
> #include <boost/utility/enable_if.hpp>
> #include <boost/type_traits/is_same.hpp>
>
> template <typename T>
> � � BOOST_CONCEPT_REQUIRES(
> � � � � � � (( boost::SinglePassRangeConcept<T> )),
> // � � � � � � ( void ))
> � � � � � � ( typename boost::enable_if<boost::is_same<typename boost::range_value<T>::type, int>, void>::type ))
> � � f( const T & ) { }
>
> int main( )
> {
> � � std::vector<int> v;
> � � f( v );
> }
>
> g++ � �-c -o enable_if.o enable_if.cpp
> enable_if.cpp: In function �int main()�:
> enable_if.cpp:17: error: no matching function for call to �f(std::vector<int, std::allocator<int> >&)�
>
> If I comment out the enable_if line and comment in the void line it's fine.
It looks like the trick is to put the enable_if outside the
BOOST_CONCEPT_REQUIRES, as in:
template <typename T>
typename enable_if<
condition,
BOOST_CONCEPT_REQUIRES(concept, (void))>::type
Paragraph 4 of [dcl.fct] (in the latest draft) seems to say that the
SFINAE error you are getting is required: only the specific type void,
written in a non-dependent way, counts as a valid function parameter type.
-- Jeremiah Willcock
It looks like the trick is to put the enable_if outside the BOOST_CONCEPT_REQUIRES, as in:
template <typename T>
typename enable_if<
condition,
BOOST_CONCEPT_REQUIRES(concept, (void))>::type
Paragraph 4 of [dcl.fct] (in the latest draft) seems to say that the SFINAE error you are getting is required: only the specific type void, written in a non-dependent way, counts as a valid function parameter type.
The internals of BOOST_CONCEPT_REQUIRES take the type that you give as the
return type and use it as a function parameter type (that is why you need
the parentheses around the outside). That is where those rules in the
standard get involved.
-- Jeremiah Willcock
> On Tue, 27 Mar 2012, Robert Jones wrote:
>
>> Hi Peeps
>> Can anyone cast any light on this...
>>
>> I want to write function which accepts a single pass range of X's, so something like this
>>
>> struct X { };
>>
>> template <typename T>
>> BOOST_CONCEPT_REQUIRES(
>> (( boost::SinglePassRangeConcept<T> )),
>> ( typename boost::enable_if<boost::is_same<typename
>> boost::range_value<T>::type, X>, void>::type ))
>> my_function( const T & range );
>>
>> Is that a reasonable construction, or is there a better way to say it?
>>
>> Next, it doesn't seem to work. It does seem to work if the type to
>> which enable_if resolves is anything
>> except void, but not for void. Why is this?
>
> Does it only fail if you try to pass something in that is not a range?
> I'm not sure that BOOST_CONCEPT_REQUIRES does SFINAE, but if it does,
It doesn't.
--
Dave Abrahams
BoostPro Computing
http://www.boostpro.com
_______________________________________________
Boost-users mailing list
Boost...@lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users