Jakub Nurski
Jakub Nurski

Reputation: 501

Function as an argument of a constructor of std::function wrapper

I am writing Monitor class for synchronization problem and I would like to implement an 'Entry' class that will wrap a std::function.

I implemented it a bit, used function traits, but right now I am only able to construct Entry objects using prepared std::function object. Attempts to write a constructor that has an plain function as a parameter failed with compiler messages about template argument deduction/substitution and <anonymous> parameter.

The program is working but I am just curious how to implement given constructor, this is my code:

template <class F>
struct FunctionType;
template <class R, class Object, class... Args>
struct FunctionType<R (Object::*)(Args...)> {
  typedef R return_type;
};
template <class R, class Object, class... Args>
struct FunctionType<R (Object::*)(Args...) const> {
  typedef R return_type;
};


template <class F> class Entry {
    std::function<F> internalFunction;

    ...

public:
    template <F> Entry(const F& function){
        // It doesn't work.
    }

    template <F> Entry(const std::function<F> function) :
        internalFunction(function) {

    }

    template<F, class... Arguments>
    typename FunctionType<F>::return_type operator()(Arguments... arguments){
        return internalFunction(arguments...);
    }
};

Upvotes: 2

Views: 926

Answers (1)

AndyG
AndyG

Reputation: 41100

A couple of things:

template<F>

doesn't make any sense at all. You get the type of F from the template parameter on the class, use that and remove this altogether.

Next, it's probably easier for you to use a trailing return type on your operator() function:

template<class... Arguments>
auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...))
{
  return internalFunction(arguments...);
}

(If you have C++14 you can just use auto).

Live Demo


Here's your fixed class

template <class F> class Entry {
    std::function<F> internalFunction;

public:
    Entry(const F& function){
        // It doesn't work.
    }

    Entry(const std::function<F> function) :
        internalFunction(function) {

    }

    template<class... Arguments>
    auto operator()(Arguments... arguments) -> decltype(internalFunction(arguments...)){
        return internalFunction(arguments...);
    }
};

Upvotes: 2

Related Questions