1

我一直很难理解std::function模板。它似乎使用了我还不知道的魔法。它的模板参数是class R, class... ARGS。然而,它可以作为std::function<void>或传递给模板std::function<void()>。带有参数的示例:std::function<void, int, float>std::function<void(int, float)>这是c++11中引入的第二种语法吗?我不认为这在以前是有效的。

另外,有没有办法获取decltype函数并将其传递给函数模板?这将使功能模板的设置变得更加容易。

这是一个例子:

#include <functional>
using namespace std;

///////////////////////////////////////////////////////////////////////////////
// this works
void x() {}
void y(int p0) {}

int main1()
{
  using namespace std::placeholders;
  function<decltype(y)> functors[] = { bind(x), bind(y, _1) };
  functors[0](1);
  functors[1](1);
  return 0;
}

///////////////////////////////////////////////////////////////////////////////
// this doesn't work
struct X
{
    void x() {}
    void y(int p0) {}
    void z(int i, int p0)
    {
      using namespace std::placeholders;
      static function<decltype(&X::y)> functors[] = { bind(&X::x, _1), bind(&X::y, _1, _2) };
      functors[i](this, p0);
    }
};

int main2()
{
  X xobj;
  xobj.z(0, 1);
  xobj.z(1, 1);
  return 0;
}

int main()
{
    return main1() + main2();
}
4

2 回答 2

4

std::function接受一个模板参数,该参数必须是函数类型。你不能使用std::function<void, int, float>. std::function<void(int, float)>是唯一有效的语法。

std::function在 C++11 中引入。std::function在此之前没有。但是,在 TR1中std::tr1::function定义了使用相同的std::function<void(int, float)>语法。

于 2013-10-09T20:25:43.390 回答
2

decltype您正在寻找的东西可能是这样的:

template<typename T>
struct transform_to_free_function;

template <typename Target, typename R, typename... Args>
struct transform_to_free_function<R (Target::*)(Args...)>
{
    using type = R(Target*, Args...);
};

注意:1)type现在是public成员 2) 它应该是函数类型,而不是用于此目的的指针。从指针类型创建非指针类型并不简单,否则您必须在std::remove_pointer其上使用 a 。

然后,您的示例的其余部分可以正常编译:

#include <functional>
using namespace std;

template<typename T>
struct transform_to_free_function;

template <typename Target, typename R, typename... Args>
struct transform_to_free_function<R (Target::*)(Args...)>
{
    using type = R(Target*, Args...);
};

struct X
{
    void x() {}
    void y(int p0) {}
    void z(int i, int p0);
};

void X::z(int i, int p0)
{
    using namespace std::placeholders;
    static function<transform_to_free_function<decltype(&X::y)>::type>
    functors[] = { bind(&X::x, _1), bind(&X::y, _1, _2) };
    functors[i](this, p0);
}

int main()
{
    X xobj;
    xobj.z(0, 1);
    xobj.z(1, 1);
    return 0;
}
于 2013-10-09T22:06:52.583 回答