もっと複雑です...変数をキャプチャする内部ラムダ関数はそのような関数ではなく、データ構造です。開発されたソリューションが見つからず、多くのリクエストと質問が解決されていない場合、std :: functionやその他の標準関数や依存関係を使用しないラムダポインタをラップするための最小限のコードを開発しました。 Pure C++ 11。
すべての種類のラムダキャプチャ、参照による参照、戻り値のvoidを受け入れ、トップレベルの関数とメンバメソッドをサポートします。
// Type checkers
template<typename _Type>
struct IsVoid
{
static const bool value = false;
};
template<>
struct IsVoid<void>
{
static const bool value = true;
};
// Callable signature interfce
template<typename _ReturnType, typename..._ArgTypes>
struct Callable
{
typedef _ReturnType ReturnType;
typedef _ReturnType (*SignatureType)(_ArgTypes...);
virtual _ReturnType operator()(_ArgTypes...args) = 0;
};
// Function and lambda closure wrapper
template<typename _ClosureType, typename _ReturnType, typename..._ArgTypes>
struct Closure: public Callable<_ReturnType, _ArgTypes...>
{
typedef _ClosureType ClosureType;
const _ClosureType closureHandler;
Closure(const _ClosureType& handler)
: closureHandler(handler)
{
}
_ReturnType operator()(_ArgTypes...args) override
{
if(IsVoid<_ReturnType>::value)
closureHandler(args...);
else
return closureHandler(args...);
}
};
// Fuction template selector
template <typename _FunctionType>
class Function
: public Function<decltype(&_FunctionType::operator())>
{
};
// Function, lambda, functor...
template <typename _ReturnType, typename... _ArgTypes>
class Function<_ReturnType(*)(_ArgTypes...)>
{
public:
typedef Function<_ReturnType(*)(_ArgTypes...)> SelfType;
typedef _ReturnType(*SignatureType)(_ArgTypes...);
Callable<_ReturnType, _ArgTypes...>* callableClosure;
Function(_ReturnType(*function)(_ArgTypes...))
: callableClosure(new Closure<SignatureType, _ReturnType, _ArgTypes...>(function))
{
}
// Captured lambda specialization
template<typename _ClosureType>
Function(const _ClosureType& function)
: callableClosure(new Closure<decltype(function), _ReturnType, _ArgTypes...>(function))
{
}
_ReturnType operator()(_ArgTypes... args)
{
if(IsVoid<_ReturnType>::value)
(*callableClosure)(args...);
else
return (*callableClosure)(args...);
}
};
// Member method
template <typename _ClassType, typename _ReturnType, typename... _ArgTypes>
class Function<_ReturnType(_ClassType::*)(_ArgTypes...)>
{
public:
typedef Function<_ReturnType(_ClassType::*)(_ArgTypes...)> SelfType;
typedef _ReturnType(_ClassType::*SignatureType)(_ArgTypes...);
SignatureType methodSignature;
Function(_ReturnType(_ClassType::*method)(_ArgTypes...))
: methodSignature(method)
{
}
_ReturnType operator()(_ClassType* object, _ArgTypes... args)
{
if(IsVoid<_ReturnType>::value)
(object->*methodSignature)(args...);
else
return (object->*methodSignature)(args...);
}
};
// Const member method
template <typename _ClassType, typename _ReturnType, typename... _ArgTypes>
class Function<_ReturnType(_ClassType::*)(_ArgTypes...) const>
{
public:
typedef Function<_ReturnType(_ClassType::*)(_ArgTypes...) const> SelfType;
typedef _ReturnType(_ClassType::*SignatureType)(_ArgTypes...) const;
SignatureType methodSignature;
Function(_ReturnType(_ClassType::*method)(_ArgTypes...) const)
: methodSignature(method)
{
}
_ReturnType operator()(_ClassType* object, _ArgTypes... args)
{
if(IsVoid<_ReturnType>::value)
(object->*methodSignature)(args...);
else
return (object->*methodSignature)(args...);
}
};
テスト:
#include <iostream>
class Foo
{
public:
int bar(int a, int b)
{
return a + b;
}
};
int someFunction(int a, int b)
{
return a + b;
}
int main(int argc, char** argv)
{
int a = 10;
int b = 1;
// Lambda without capturing
Function<int(*)(int)> fn1([] (int b) -> int {
return b;
});
std::cout << fn1(2) << std::endl; // 2
// Lambda capturing variable
Function<int(*)(int)> fn2([a] (int c) -> int {
return a + c;
});
std::cout << fn2(-7) << std::endl; // 3
// Lambda capturing scope
Function<int(*)(int)> fn3([&] (int c) -> int {
return a + c;
});
std::cout << fn3(-5) << std::endl; // 5
// Arguments by reference
Function<void(*)(int&, int)> fn4([] (int& d, int f) {
d = d + f;
});
fn4(a, -3); // Void call
std::cout << a << std::endl; // 7
// Top level function reference
Function<int(*)(int, int)> fn6(someFunction);
std::cout << fn6(a, 4) << std::endl; // 11
// Member method
Foo* foo = new Foo();
Function<int(Foo::*)(int,int)> fn7(foo->bar);
std::cout << fn7(foo, a, 8) << std::endl; // 15
}
はGCC 4.9 WIH正しく動作します。
ご質問ありがとうございます。
'のstd :: function'、例えば、'のstd ::機能 Fを使用します;そして 'F(int、int b){return a + b;});' –