2

所以我有以下代码:

#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 中使用特定类型(例如 funcky)的“this”。妄想。

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

在 C++11 中这样的事情是可能的吗?我如何完成所说的事情?

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

4

2 回答 2

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引用——它不是隐式参数。因此,为它想要“另一种类型”是没有意义的。

于 2012-09-21T10:10:15.410 回答
3

如果您想为用户提供一种向您的类提供回调的方法,最好使用std::function,因为根据您的经验,在函数/仿函数类型上模板化类并不是一件非常有用的事情。

问题在于您不能只接受任何东西。您应该对可以作为回调传递的内容有明确的要求,因为您应该知道以后要如何调用它。请参阅为什么我将构造函数设为模板。

#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";});
}
于 2012-09-21T09:32:31.403 回答