所以我有以下代码:
#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,尽量不要猜测我在做什么,好像我不能这样做,我只是以更简单的方式重写它。这不值得努力。
答案 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
的延迟引用 - 它不是隐式参数。因此,想要“另一种类型”是没有意义的。