Skip to content

Last updated:2026-10-12

An Interesting Piece of C++ Code

0. Introduction

Goal: how do you get the number of parameters of a lambda or functor argument?

This section will do it with templates + ::* + decay + decltype!

1. Implementation

The final effect:

auto c1 = [](int x, double y) { return x * y; };
std::cout << argument_count<decltype(c1)>::value << std::endl;
MyClass f;
std::cout << argument_count<decltype(f)>::value << std::endl;

Output: 2

Let's think about this problem; we need to know these points:

  • How do we locate the position of the functor's or lambda's invocation operator?
  • How do we get the number of parameters in that function signature?

For the first question, we can use ::* to point to a member declaration. For both functors and lambdas it is &std::decay<F>::type::operator()). Simply put, both get the address of the operator() declaration.

Here decay is used to remove cv qualifiers. Taking the MyClass above as an example, at this point we first obtain the MyClass type through std::decay<F>::type, then get the address of its operator(), and pass it to argument_count_impl.

template <typename F>
using argument_count = decltype(argument_count_impl(&std::decay<F>::type::operator()));

The implementation of argument_count_impl is also fairly simple: use the R (F::*)(A...) signature to get the corresponding function. Here variadic templates and ::* are used; sizeof... gets the number of parameters, and integral_constant says this compile-time constant type is int with the value sizeof...(A).

template <typename F, typename R, typename... A>
static std::integral_constant<int, sizeof...(A)> argument_count_impl(R (F::*)(A...));

With that, we have implemented the feature of getting the parameter count of a lambda or functor~

Comments