C ++ 11 Lambda模板推断

时间:2012-09-21 09:10:53

标签: c++ templates lambda c++11

所以我有以下代码:

#include <iostream>

template <typename T>
class funcky
{
  public:
    funcky(char const* funcName, T func)
      : name(funcName), myFunc(func)
    {
    }

  //private:
    char const* name;
    T myFunc;
};

#if 0
int main(void)
{
  char const* out = "nothing";

  // requires template args
  funcky test("hello", [&](int x, int y) -> int
  {
    out = "YES";
    return x + y;
  });

  std::cout << test.name << " = " << test.myFunc(1, 2) << std::endl;
  std::cout << test.name << " = " << out << std::endl;

  return 0;
}

int main2(void)
{
  funcky<void(*)(void)> test("hello", [&, this](void) -> void
  {
    std::cout << this->name << std::endl;
  });

  test.myFunc();

  return 0;
}
#endif

int main(void)
{
  char const* out = "nothing";

  auto myFunc = [&](int x, int y) -> int
  {
    out = "YES";
    return x + y;
  };
  funcky<decltype(myFunc)> test("hello", myFunc);

  std::cout << test.name << " = " << test.myFunc(1, 2) << std::endl;
  std::cout << test.name << " = " << out << std::endl;

  return 0;
}

顶部块是一个函数持有者,它拥有一个lambda和一个名字。

接下来是我想要使用API​​的方法,但由于没有指定模板参数而失败。

在那之后,我想知道是否可以在一个未在其中声明的lambda中使用特定类型的“this”(例如funcky)。一厢情愿。

最后是编译但在funcky构造函数和decltype之外使用lambda的代码。

C ++ 11中是否可以实现这些功能?我如何完成所说的事情?

除非它可以有相同的API,尽量不要猜测我在做什么,好像我不能这样做,我只是以更简单的方式重写它。这不值得努力。

2 个答案:

答案 0 :(得分:3)

如果你想为用户提供一种为你的类提供回调的方法,你最好使用std::function,因为在函数/函子类型上模板化的类对于它来说并不是一件非常有用的事情。做,就像你经历的那样。

问题来自于你不能随便拿走任何东西。你应该对可以作为回调传递的内容有明确的要求,因为你应该知道以后如何调用它。请参阅this,了解为何将构造函数设为模板。

#include <functional>
#include <utility>

struct X{
  template<class F>
  X(F&& f) : _callback(std::forward<F>(f)) {} // take anything and stuff it in the 'std::function'

private:
  std::function<int(int,int)> _callback;
};

int main(){
  X x([](int a, int b){ return a + b; });
}

但是,如果不知道将如何调用回调(比如,用户稍后会传递参数),但是你想支持它,那么模板你的类型回调的签名

#include <iostream>
#include <functional>
#include <utility>

template<class Signature>
struct X{
  template<class F>
  X(F&& f) : _callback(std::forward<F>(f)) {} // take anything and stuff it in the 'std::function'

private:
  std::function<Signature> _callback;
};

int main(){
  X<int(int,int)> x1([](int a, int b){ return a + b; });
  X<void()> x2([]{ std::cout << "wuzzah\n";});
}

答案 1 :(得分:3)

这样的东西
template<typename Functor>
funcky<typename std::decay<Functor>::type>
make_funcky(const char* name, Functor&& functor)
{ return { name, std::forward<Functor>(functor) }; }

可能对以下内容有所帮助:

auto test = make_funcky("hello", [&](int x, int y) -> int
{
    out = "YES";
    return x + y;
});

但是,在lambda表达式中this总是引用表达式之外的直接this。它不是对调用时存在的某些this延迟引用 - 它不是隐式参数。因此,想要“另一种类型”是没有意义的。