Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using the type of the function in std::function to declare multiple functions of that type

Tags:

c++

c++11

Suppose I have

typedef std::function<
    double(
        int,
        long
    )
> FooType;

and I want to declare function prototypes for a series of functions that I can slot into a std::function of this type. I know I can write

double foo1(int, long);
double foo2(int, long);

etc., but is there a way I can use FooType somehow when declaring the function prototypes? Something like

FooType::type foo1, foo2;

Perhaps I might have to use (*foo1) or similar? Naturally in the implementation of the function I'd need to spell it out long hand so I can put in some parameters, but writing it as above would keep my header file cleaner.

like image 289
Michael Bullock Avatar asked Jan 12 '17 12:01

Michael Bullock


People also ask

What is a function-type?

The function-type is the data type of the value the function returns. It may be standard, user-defined scalar or subrange type but it cannot be structured type. Local declarations − Local declarations refer to the declarations for labels, constants, variables, functions and procedures, which are application to the body of function only.

What is the return type of the function being declared?

The type of the function being declared is composed from the return type (provided by the decl-specifier-seq of the declaration syntax) and the function declarator noptr-declarator ( parameter-list ) cv(optional) ref(optional) except(optional) attr(optional)

What is a function declaration at class scope?

A function declaration at class scope introduces a class member function (unless the friend specifier is used), see member functions and friend functions for details. The type of the function being declared is composed from the return type (provided by the decl-specifier-seq of the declaration syntax) and the function declarator

What is the difference between function declaration and function definition?

A function declaration tells the compiler about a function's name, return type, and parameters. A function definition provides the actual body of the function. Pascal standard library provides numerous built-in functions that your program can call.


2 Answers

Sure you can, just as always*, using partial specialization:

template <typename> struct fn_sig;
template <typename T> struct fn_sig<std::function<T>> { using type = T; };

Usage:

fn_sig<FooType>::type f;

double f(int a, long b) { return double(a) /  b; }

(You'll obviously need to spell the underlying function type out for the function definition.)



*) Meaning that this is the same answer for any question of the form "can I get the template parameter from a template specializaton".

like image 149
Kerrek SB Avatar answered Oct 23 '22 09:10

Kerrek SB


writing it as above would keep my header file cleaner

It would be cleaner (with less metaprogramming) to go the other way around: Start with the foo() declaration and create FooType from it.

double foo(int, long);

typedef std::function< decltype(foo) > FooType;

Since there are presumably several such functions, two typedefs might be the optimal factoring:

typedef double FooFn(int, long);
typedef std::function< FooFn > FooType;

FooFn foo1, foo2, foo3;

Of course, in the implementation (.cpp) file the signature needs to be written longhand.

One more thing, note that std::function is a heavyweight generalization of function pointers. If you'll only ever assign ordinary functions into it, a function pointer might be better, and this would be a drop-in replacement:

typedef FooFn * FooType;
like image 22
Potatoswatter Avatar answered Oct 23 '22 10:10

Potatoswatter