Functional traits

Functional traits provide information about a function, such as return and parameter types. The following function types are supported:

  • free functions;

  • free function pointers;

  • member function pointers (in this case the first parameter is the enclosing class);

  • function objects with a single function call operator;

  • const and reference-qualified versions of the above types.

This is a lightweight analog of Boost.CallableTraits with limited functionality.

Reference

The most convenient way to use the traits is through the following interface:

template<class Fn>
using ac::return_t = typename detail::function_traits<Fn>::return_type
template<class Fn>
size_t ac::arity_v = detail::function_traits<Fn>::arity
template<size_t Index, class Fn>
using ac::parameter_at_t = typename detail::function_traits<Fn>::template parameter_at<Index>
template<class Fn>
bool ac::accepts_variadic_arguments_v = detail::function_traits<Fn>::accepts_variadic_arguments
template<class Fn>
bool ac::is_noexcept_v = detail::function_traits<Fn>::is_noexcept

The following concepts are provided:

template<class T>
concept FreeFunction
#include <free_function.hpp>

Concept of a free function.

template<class T>
concept MemberFunction
#include <member_function.hpp>
template<class T>
concept FunctionObject
#include <function_object.hpp>

Concept of a function object, that is a type with a non-overloaded operator().

Source code

Tests

Design

The following reference was used at first, but it was heavily expanded.

Qualified free functions

Boost.CallableTraits supports qualified free function types like

Return(Args...) const volatile &

These types indeed exist in C++, but declaring a function like void f() const {} results in a compilation error. This is confirmed by cppreference:

cv - const/volatile qualification, only allowed in non-static member function declarations

ref - (since C++11) ref-qualification, only allowed in non-static member function declarations

It’s not clear why such types exist if they cannot be used in a declaration. For this reason, our function traits don’t support them.