Checking for return type -- BOOST_STATIC_ASSERT?

I'd like to be able to make certain that a function/functor returns a double precision floating point value. I was always under the impression that it's essentially impossible to check things based on return type. Is there a way to do this? Something like BOOST_STATIC_ASSERT, who knows perhaps that *can* do it.. Ideally I would like to have some sort of compile type warning so that in the following context, class myclass { public: ... template <class O> a_func(O functor) { ASSERT_IS_A_FUNCTOR(O); ASSERT_RETURN_TYPE_CONVERTABLE_TO_FLOAT(O); } }; if O is compatible with the concept of a functor and O returns a type that can be converted to a float, then we are good to go -- otherwise I'd like an intelligible error. If, for example, O is of the type 'void (*)()' I'd like it (the compiler) to spit out, "The function pointer of type O must of signature float (*)()" Any ideas? -ed ------------------------------------------------ "No more boom and bust." -- Dr. J. G. Brown, 1997

2009/8/20 Edward Grace <ej.grace@imperial.ac.uk>:
if O is compatible with the concept of a functor and O returns a type that can be converted to a float, then we are good to go -- otherwise I'd like an intelligible error.
If, for example, O is of the type 'void (*)()' I'd like it (the compiler) to spit out, "The function pointer of type O must of signature float (*)()"
Sounds like you want something like the MPL_ASSERT example at [1] along with the result_of metafunction[2]. [1] http://www.boost.org/doc/libs/1_39_0/libs/mpl/doc/refmanual/assert.html [2] http://www.boost.org/doc/libs/1_39_0/libs/utility/utility.htm#result_of HTH, ~ Scott

On 20 Aug 2009, at 23:57, Scott McMurray wrote:
2009/8/20 Edward Grace <ej.grace@imperial.ac.uk>:
if O is compatible with the concept of a functor and O returns a type that can be converted to a float, then we are good to go -- otherwise I'd like an intelligible error.
If, for example, O is of the type 'void (*)()' I'd like it (the compiler) to spit out, "The function pointer of type O must of signature float (*)()"
Sounds like you want something like the MPL_ASSERT example at [1] along with the result_of metafunction[2].
[1] http://www.boost.org/doc/libs/1_39_0/libs/mpl/doc/refmanual/ assert.html
[2] http://www.boost.org/doc/libs/1_39_0/libs/utility/ utility.htm#result_of
HTH, ~ Scott
Thanks for that tip Scott. Knowing where to look is always half the battle. I think I want to do something like the following (ignore _TEMPLATE_ and _TIMER_, they just expand to the usual template and scope for a template class). _TEMPLATE_ template <class O1, class O2> void _TIMER_ measure_percentage_speedup(O1 fa, O2 fb, double &MinPercent, double &MedPercent, double &MaxPercent) { // We want to make sure that the functions return something. // the following doesn't seem to work. typedef typename boost::result_of<O1()>::type result_of_fa; typedef typename boost::result_of<O2()>::type result_of_fb; BOOST_MPL_ASSERT(( boost::is_same<result_of_fa, unsigned> )); BOOST_MPL_ASSERT(( boost::is_same<result_of_fb, unsigned> )); ... ... No joy --- I can stick in whatever function type I want, with whatever return type (e.g. void) and the asserts don't complain. Is the above the type of thing you had in mind or have I got the wrong end of the stick? For what it's worth, I get an error if returning void from the function f() because of this subsequent line, in another part of the code, // Time a set of function calls. t0 = chrono(); for (counter n=0; n < iterations; ++n) test::live_code += f(); t1 = chrono(); however I'd like to make this requirement of a non-void return something more obvious. Thanks, -ed

On 20 Aug 2009, at 23:57, Scott McMurray wrote:
2009/8/20 Edward Grace <ej.grace@imperial.ac.uk>:
if O is compatible with the concept of a functor and O returns a type that can be converted to a float, then we are good to go -- otherwise I'd like an intelligible error.
If, for example, O is of the type 'void (*)()' I'd like it (the compiler) to spit out, "The function pointer of type O must of signature float (*)()"
Sounds like you want something like the MPL_ASSERT example at [1] along with the result_of metafunction[2].
I'm starting to wonder if there's a problem with BOOST_MPL_ASSERT in g ++, as I understand it (this is quite probably the real problem....) the following minimal example should work #include <boost/mpl/assert.hpp> int main() { BOOST_MPL_ASSERT(( boost::is_same<unsigned,unsigned> )); // Should be ok! return 0; } When compiling, /sw/bin/g++-4 -I/usr/local/include -ansi -pedantic -Wall test.cpp test.cpp: In function 'int main()': test.cpp:4: error: expected primary-expression before 'enum' test.cpp:4: error: expected ';' before 'enum' Pre-processing (and smartening up for presentation) we get, int main() { static __const std::size_t mpl_assertion_in_line_4 = sizeof( boost::mpl::assertion_failed<false>( boost::mpl::assert_arg( (void (*) ( boost::is_same<unsigned,unsigned> ))0, 1 ) // <--- ))0,1 ) ???? ) ) ; // Should be ok! return 0; } -ed

<snip> </snip>
#include <boost/mpl/assert.hpp>
int main() { BOOST_MPL_ASSERT(( boost::is_same<unsigned,unsigned> )); // Should be ok! return 0; }
When compiling,
/sw/bin/g++-4 -I/usr/local/include -ansi -pedantic -Wall test.cpp test.cpp: In function 'int main()': test.cpp:4: error: expected primary-expression before 'enum' test.cpp:4: error: expected ';' before 'enum'
Pre-processing (and smartening up for presentation) we get,
int main() { static __const std::size_t mpl_assertion_in_line_4 = sizeof( boost::mpl::assertion_failed<false>( boost::mpl::assert_arg( (void (*) ( boost::is_same<unsigned,unsigned> ))0, 1 ) // <--- ))0,1 ) ???? ) ) ; // Should be ok! return 0; }
You should also include <boost/type_traits/is_same.hpp> Regards, Neil Groves

#include <boost/mpl/assert.hpp>
int main() { BOOST_MPL_ASSERT(( boost::is_same<unsigned,unsigned> )); // Should be ok! return 0; }
[snip]
You should also include <boost/type_traits/is_same.hpp>
Duh - feeling pretty dim..... #include <boost/mpl/assert.hpp> #include <boost/type_traits/is_same.hpp> int main() { BOOST_MPL_ASSERT(( boost::is_same<unsigned,double> )); // Should die! return 0; } /sw/bin/g++-4 -I/usr/local/include -ansi -pedantic -Wall test.cpp test.cpp: In function 'int main()': test.cpp:6: error: no matching function for call to 'assertion_failed (mpl_::failed************ boost::is_same<unsigned int, double>::************)' Bingo! Cheers, Now to try and build my castle in the sky (lets face it that's what a lot of this feels like at times)..... -ed

On 20 Aug 2009, at 23:57, Scott McMurray wrote:
2009/8/20 Edward Grace <ej.grace@imperial.ac.uk>:
if O is compatible with the concept of a functor and O returns a type that can be converted to a float, then we are good to go -- otherwise I'd like an intelligible error.
If, for example, O is of the type 'void (*)()' I'd like it (the compiler) to spit out, "The function pointer of type O must of signature float (*)()"
Sounds like you want something like the MPL_ASSERT example at [1] along with the result_of metafunction[2].
[1] http://www.boost.org/doc/libs/1_39_0/libs/mpl/doc/refmanual/ assert.html
[2] http://www.boost.org/doc/libs/1_39_0/libs/utility/ utility.htm#result_of
Sorted! It turns out that the other problem I was having as also not including is_same.hpp.... Thanks for the pointers (excuse the C pun). Curiously, littering my code with these assertions has now highlighted some (genuine) wrinkles that I hadn't spotted before. Regards, -ed ------------------------------------------------ "No more boom and bust." -- Dr. J. G. Brown, 1997

On 21 Aug 2009, at 11:09, Philippe Vaucher wrote:
I'd like to be able to make certain that a function/functor returns a double precision floating point value.
Looks like you found your solution, however I'd like to point to boost::enable_if, which might be a good alternative to do what you want.
Thanks, I'll take a look... -ed
participants (4)
-
Edward Grace
-
Neil Groves
-
Philippe Vaucher
-
Scott McMurray