Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ wrap a generic std::tr1::function with another function

Tags:

c++

How can I wrap a generic C++ std::tr1::function object with another function such that this function executes first followed by the wrapped function? I've tried:

#include <tr1/functional>

template <typename T>
int wrapped(const std::tr1::function<int(T)>& f, T t)
{
  return f(t);
}

template <typename T>
std::tr1::function<int(T)> wrap(const std::tr1::function<int(T)>& f)
{
  return std::tr1::bind(&wrapped, f, std::tr1::placeholders::_1);
}

int foo(int i) { return i; }

int main(int argc, char** argv)
{
  std::tr1::function<int(int)> f =
    wrap(std::tr1::bind(&foo, std::tr1::placeholders::_1));
  f(1);
  return 0;
}

But this returns with the compiler error (g++):

wrap.cpp: In function ‘int main(int, char**)’:
wrap.cpp:22: error: no matching function for call to ‘wrap(std::tr1::_Bind<int (* ()(std::tr1::_Placeholder<1>))(int)>)’
like image 267
benjamin Avatar asked Apr 29 '26 19:04

benjamin


1 Answers

I see two problems in your code. First, wrapped is not a function, it is a function template, and as such it doesn't exist in the generated program. You can't take an address of a function template. You should instead specify an instantiation of this template to take address of:

template <typename T>
std::tr1::function<int(T)> wrap(const std::tr1::function<int(T)>& f)
{
  return std::tr1::bind(&wrapped<T>, f, std::tr1::placeholders::_1);
}

Second (and thats what your compiler is trying to tell you) you must explicitly specify a template parameter when calling wrap. The compiler can't deduce tha parameter from supplied arguments.

std::tr1::function<int(int)> f =
  wrap<int>(std::tr1::bind(&foo, std::tr1::placeholders::_1));

I don't really understand how std::bind or tr1::bind works on the inside. But I understand that the returned type is very different from a simple function pointer, and as such doesn't allow the compiler to clearly read the type for template parameter deduction. So in these situations you need to specify the type explicitly.

like image 184
Fiktik Avatar answered May 01 '26 09:05

Fiktik