C++ std::function 구현에 대해
오래전부터 std::function에 대해 꽤 궁금해왔다.
그 이유는 std::function<int(void)> 이런 형태이기 때문이다.
이를 어떻게 만들려면 어떻게 해야하나
맨첨에 생각할때는 다음과 같이 생각하였지만.
이는 내가 원하는 방식이 아니므로 넘어갔다.
1
2
3
4
5
6
|
template <typename T, typename… Args>
class function{
}
|
cs |
비주얼 스튜디오에는 std::function코드는 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
template<class _Tx>
struct _Get_function_impl;
#define _GET_FUNCTION_IMPL(CALL_OPT, X1, X2, X3) \
template<class _Ret, \
class… _Types> \
struct _Get_function_impl<_Ret CALL_OPT (_Types…)> \
{ /* determine type from argument list */ \
typedef _Func_class<_Ret, _Types…> type; \
};
};
// CLASS TEMPLATE function
template<class _Fty>
class function
: public _Get_function_impl<_Fty>::type
{ // wrapper for callable objects
private:
typedef typename _Get_function_impl<_Fty>::type _Mybase;
public:
function() _NOEXCEPT
{ // construct empty function wrapper
}
function(nullptr_t) _NOEXCEPT
{ // construct empty function wrapper from null pointer
}
|
cs |
위 소스를 보면 std::function<int(void)> 이게 왜 되는지 이해가 됬다.
템플릿 인자안에 들어가는 int(void)이부분이 이미 타입이 여러개가 아니라 타입이기 때문에 템플릿 인자에 하나만 넣은거다.
_Get_function_impl클래스는 다음과같다.
1
|
template<class _Tx>
struct _Get_function_impl;
#define _GET_FUNCTION_IMPL(CALL_OPT, X1, X2, X3) \
template<class _Ret, \
class… _Types> \
struct _Get_function_impl<_Ret CALL_OPT (_Types…)> \
{ /* determine type from argument list */ \
typedef _Func_class<_Ret, _Types…> type; \
};
};
typedef typename _Get_function_impl<_Fty>::type _Mybase;
|
cs |
_Get_function_impl은 먼저 몸체없이 전방선언을 해두고 아래에 특수화 한번 해주었다.
그로 인해 반환형도 쉽게 구분 지울수 있게된다.
이해 하기 힘들거같아 다음과 같이 프로토타입을 만들어 두었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
template <typename T>
class function;
template <typename R, typename… Args>
class function<R(Args…)>
{
public:
typedef R(*np)(Args…);
np a;
};
void fn(int a) {
std::cout << “asdad”;
}
int main() {
function<void(int)> a;
a.a = fn;
a.a(10);
}
|
cs |