[type_traits] has_member_function_callable_with

Hi to all, Trying to port C++11 code (allocator_traits) to C++03 (without decltype support), I needed to check at compile time if a member function can be called with some given parameters. Typical solutions I found on the net were based on specific signatures, say: const bool value = HAS_MEMBER_FUNCTION_FUNCNAME_WITH_SIGNATURE(MyClass, (int, char*)); However, it is not feasible to know the exact signature as I want to deal with conversions, const references, etc. Luckily, I found a very interesting explanation in Proto documentation: http://www.boost.org/doc/libs/1_47_0/doc/html/proto/appendices.html#boost_pr... Based on this, I've tried to write my solution and I'd like to share it here with type traits experts, in case someone knows a better solution (see attached example). I know I don't take into account many issues for a truly generic utility (const member functions, etc.) but please let me know if you find this example interesting. Best, Ion

On 9/15/2011 5:18 PM, Ion Gaztañaga wrote:
Hi to all,
Trying to port C++11 code (allocator_traits) to C++03 (without decltype support), I needed to check at compile time if a member function can be called with some given parameters.
Typical solutions I found on the net were based on specific signatures, say:
const bool value = HAS_MEMBER_FUNCTION_FUNCNAME_WITH_SIGNATURE(MyClass, (int, char*));
However, it is not feasible to know the exact signature as I want to deal with conversions, const references, etc. Luckily, I found a very interesting explanation in Proto documentation:
http://www.boost.org/doc/libs/1_47_0/doc/html/proto/appendices.html#boost_pr...
Based on this, I've tried to write my solution and I'd like to share it here with type traits experts, in case someone knows a better solution (see attached example). I know I don't take into account many issues for a truly generic utility (const member functions, etc.) but please let me know if you find this example interesting.
Thanks, Ion, I definitely want to look at your solution. I also know the link above as it has come up before. In TTI one can test for an exact signature but I want to pursue solutions based on Eric Niebler's Proto explanation and your solution also for future enhancements.

2011/9/15 Ion Gaztañaga <igaztanaga@gmail.com>:
Hi to all,
Trying to port C++11 code (allocator_traits) to C++03 (without decltype support), I needed to check at compile time if a member function can be called with some given parameters.
Take a look at: http://svn.boost.org/svn/boost/trunk/boost/unordered/detail/allocator_helper... It contains an incomplete implementation of allocator_traits. I just used sizeof instead of decltype for compilers which support SFINAE expressions - gcc 4.4+, clang, and visual studio 2008+ (sort of). Look for the line: #if !defined(BOOST_NO_SFINAE_EXPR) || BOOST_WORKAROUND(BOOST_MSVC, >= 1500) If you can decipher it you might notice some apparently superfluous code which is required to use SFINAE expressions with Visual C++. I'll write some more when I get a chance. I'll have a look at your trait implementation as it might be better for other compilers.

On 16 September 2011 00:32, Daniel James <dnljms@gmail.com> wrote:
2011/9/15 Ion Gaztañaga <igaztanaga@gmail.com>:
Hi to all,
Trying to port C++11 code (allocator_traits) to C++03 (without decltype support), I needed to check at compile time if a member function can be called with some given parameters.
Take a look at:
http://svn.boost.org/svn/boost/trunk/boost/unordered/detail/allocator_helper...
Oh, and very rough and incomplete documentation of its inadequacies at: http://boost-sandbox.sourceforge.net/doc/html/unordered/compliance.html

El 16/09/2011 1:32, Daniel James escribió:
2011/9/15 Ion Gaztañaga<igaztanaga@gmail.com>:
Hi to all,
Trying to port C++11 code (allocator_traits) to C++03 (without decltype support), I needed to check at compile time if a member function can be called with some given parameters.
Take a look at:
http://svn.boost.org/svn/boost/trunk/boost/unordered/detail/allocator_helper...
It contains an incomplete implementation of allocator_traits. I just used sizeof instead of decltype for compilers which support SFINAE expressions - gcc 4.4+, clang, and visual studio 2008+ (sort of). Look for the line:
Thanks for the info, I didn't know about the existence of SFINAE expressions with sizeof. One of the shortcomings of my proposal is supporting 0 argument functions, I haven't found yet a way to reliably detect them. Best, Ion

2011/9/18 Ion Gaztañaga <igaztanaga@gmail.com>:
Thanks for the info, I didn't know about the existence of SFINAE expressions with sizeof. One of the shortcomings of my proposal is supporting 0 argument functions, I haven't found yet a way to reliably detect them.
I think that for those cases in allocator_traits ('has_select_on_container_copy_construction' and 'max_size'), just checking that a member exists would be sufficient and is probably better than what I've currently got. If there's a member function with the wrong signature or a variable, a compile error wouldn't be particularly problematic.

On Wed, Sep 21, 2011 at 2:23 PM, Daniel James <dnljms@gmail.com> wrote:
2011/9/18 Ion Gaztañaga <igaztanaga@gmail.com>:
Thanks for the info, I didn't know about the existence of SFINAE
expressions
with sizeof. One of the shortcomings of my proposal is supporting 0 argument functions, I haven't found yet a way to reliably detect them.
I think that for those cases in allocator_traits ('has_select_on_container_copy_construction' and 'max_size'), just checking that a member exists would be sufficient and is probably better than what I've currently got. If there's a member function with the wrong signature or a variable, a compile error wouldn't be particularly problematic.
FWIW, I've resorted to just exhausting all combinations of compatible const qualifiers on the class type together with all const and/or reference qualifiers on the result type, and testing for each of these *exact* signatures (which would miss implicit conversions on the result type other than those involving just const and reference qualifiers). I don't know if this is better or worse, on balance, than Daniel's suggestion; at best, I'd say only marginally better. - Jeff
participants (4)
-
Daniel James
-
Edward Diener
-
Ion Gaztañaga
-
Jeffrey Lee Hellrung, Jr.