It’s artificial (generated with the ever-helpful geordi bot), although I’m sure that if you looked hard enough, a similar one would appear somewhere in the wild. In the above case, foo is a pointer to function taking pointer to function taking char* and char* and returning int returning pointer to array of char*. I think that even seasoned C and C++ programmers will agree that this is quite confusing at first glance. Or second. And third. Especially for people less versed in “C gibberish”, as cdecl.org aptly calls it.

Even though C++ programmers, with the advent of functors and templates, don’t need to use raw function pointers often, they are still sometimes present – for example when paying for std::function‘s type erasure is unacceptable and there’s no state to be held in an object. Fortunately in C++11, instead of creating a C-style typedef for each such type, it’s possible to use a generalized solution that uses familiar syntax already used in the aforementioned std::function.

The usage is identical to that of std::function, but it’s lightweight and doesn’t add any overhead over the function pointer – it is exactly the same type (int (*foo)(int) becomes function_ptr<int(int)> foo).

In the same vein, C-style arrays could be replaced with saner (the type being on the left hand side of the declaration, not all around it) aliases, with the syntax being close to that of the std::array class:

template<typename T, std::size_t S>using c_array = T[S];

template <typename T, std::size_t S>
using c_array = T[S];

And the example usage would look as follows:

// int arr1[10]
c_array<int,10> arr2;

// int arr1[10]
c_array<int,10> arr2;

Although for writing new code, I’d stick with std::array. The above implementation doesn’t account for arrays of unknown bound, but it can be easily fixed by using a helper struct (as alias templates cannot be specialized). Zero-sized arrays are illegal in C++ so zero may be used to specify array of unknown bound:

With the above, main could be declared as int main(int argc, c_array<char*> argv), or even int main(int argc, c_array<c_string> argv), if one bothered to alias char* as well. I think it conveys the intent a lot more clearly than the standard char**.

With the above type aliases, the first example could redeclared as

function_ptr<c_array<char*>*(function_ptr<int(char*,char*)>)> foo

function_ptr<c_array<char*>*(function_ptr<int(char*,char*)>)> foo

While still far from being clear, I do think that this is easier (and faster) to reason about than