함수 포인터 유형 반환
종종 함수 포인터를 반환하는 함수를 작성할 필요가 있습니다. 할 때마다 사용하는 기본 형식은 다음과 같습니다.
typedef int (*function_type)(int,int);
function_type getFunc()
{
function_type test;
test /* = ...*/;
return test;
}
그러나 이것은 많은 함수를 다룰 때 번거로울 수 있으므로 각 함수 (또는 각 함수 클래스)에 대해 typedef를 선언 할 필요가 없습니다.
typedef를 제거하고 함수에서 반환 된 지역 변수를 다음과 같이 선언 할 수 있습니다 int (*test)(int a, int b);
. 함수 본문을 다음과 같이 만듭니다.
{
int (*test)(int a, int b);
test /* = ...*/;
return test;
}
하지만 함수의 반환 유형에 대해 무엇을 설정 해야할지 모르겠습니다. 나는 시도했다 :
int(*)(int,int) getFunc()
{
int (*test)(int a, int b);
test /* = ...*/;
return test;
}
하지만 구문 오류를보고합니다. 함수 포인터에 대한 typedef를 선언하지 않고 그러한 함수에 대한 반환 유형을 어떻게 선언합니까? 가능할까요? 또한 각 함수에 대해 typedef를 선언하는 것이 더 깔끔한 것처럼 보이지만 코드를 최대한 깔끔하고 따르기 쉽게 구성하는 데 매우주의를 기울입니다. typedef를 제거하고 싶은 이유는 검색 함수를 선언하는 데만 사용되기 때문에 코드에서 중복되어 보이기 때문입니다.
int (*getFunc())(int, int) { … }
귀하가 요청한 선언을 제공합니다. 또한 ola1olsson이 지적 했듯이void
다음 을 삽입하는 것이 좋습니다 .
int (*getFunc(void))(int, int) { … }
이것은 getFunc
매개 변수를 취하지 않을 수 있으며, 이는 누군가가 getFunc(x, y)
대신 실수로 작성 하는 것과 같은 오류를 피하는 데 도움이 될 수 있습니다 getFunc()(x, y)
.
다음과 같이 할 수 있습니다.
int foo (char i) {return i*2;}
int (*return_foo()) (char c)
{
return foo;
}
하지만 신 이시여, 코드를 디버깅 할 필요가 없었 으면합니다 ....
함수 포인터를 사용하기 때문에 이미 주어진 답변보다 약간 까다 롭기 때문에 여기에 두십시오.
(int (__cdecl *)(const char *))
함수 포인터를 반환합니다.
(int (__cdecl *)(const char *))
#include <stdio.h>
int (*idputs(int (*puts)(const char *)))(const char *) {
return puts;
}
int main(int argc, char **argv)
{
idputs(puts)("Hey!");
return 0;
}
이것은 어리석은 예이지만 간단하고 오류를주지 않습니다. 정적 함수를 선언하는 것입니다.
#include <stdio.h>
#include <stdlib.h>
void * asdf(int);
static int * hjkl(char,float);
main() {
int a = 0;
asdf(a);
}
void * asdf(int a) {return (void *)hjkl; }
static int * hjkl(char a, float b) {int * c; return c;}
C ++ 클래스에서 일부 C 코드를 래핑하는 동안 원래 포스터와 동일한 바램이있었습니다 typedef
. 함수 포인터 프로토 타입에 의존하지 않고 함수에서 함수 포인터를 반환하는 것입니다. const
약간의 주제에서 벗어난 (C ++)이지만 공유 할 가치가 있다고 생각하는 C ++ 정확성 문제가 발생 했지만 원래 질문과 직접 관련이 있습니다 typedef
. .NET Framework에 의존하지 않고 C 함수 포인터를 반환하는 구문입니다 .
The code below defines a class A
which stores a function pointer and exposes it to the outside world through the get_f()
call. This is the function that should return a function pointer without a typedef
.
The point (which stumped me for some time) was how to declare that get_f()
was a const
function, i.e. it wouldn't alter A
.
The code contains 2 variants: the first uses a typedef for the function pointer prototype, whilst the second writes everything out in full. The #if
switches between the two.
#include <iostream>
int my_f(int i)
{
return i + 1;
}
#if 0 // The version using a typedef'ed function pointer
typedef int (*func_t)(int);
class A
{
public:
A(func_t f) : m_f(f) {}
func_t get_f() const { return m_f; }
private:
func_t m_f;
};
int main(int argc, char *argv[])
{
const A a(my_f);
std::cout << "result = " << a.get_f()(2) << std::endl;
}
#else // The version using explicitly prototyped function pointer
class A
{
public:
A(int (*f)(int)) : m_f(f) {}
int (*get_f() const)(int) { return m_f; }
private:
int (*m_f)(int);
};
int main(int argc, char *argv[])
{
const A a(my_f);
std::cout << "result = " << a.get_f()(2) << std::endl;
}
#endif
The expected/desired output is:
result = 3
The key point is the position of the const
qualifier in the line:
int (*get_f() const)(int) { return m_f; }
I think you've got three options:
- Stick with typedef. At the end of the day, it's typedef's job.
- Return void* and the casting it.
- Reconsider your software architecture. Perhaps you could share with us what you're trying to achieve and see if we can point you toward a better direction.
You can write the following code(It only works in C++11 and above):
//C++11
auto func(...) {
int (*fptr)(...) ret = ...
//Do sth.
return ret;//C++11 compiler will automatically deduce the return type for you
}
Or, if you do not like automatic return type deduction, you can specified the type at the end of the function(Same as above, only in C++11 and above):
//C++11
auto func(...) -> int (*)(...) { /* Do sth. */ }
ReferenceURL : https://stackoverflow.com/questions/20617067/returning-function-pointer-type
'programing' 카테고리의 다른 글
네임 스페이스 종속성이 필요하지 않습니다. (0) | 2021.01.15 |
---|---|
`hashCode`의 기본 구현은 무엇입니까? (0) | 2021.01.15 |
IACA 란 무엇이며 어떻게 사용합니까? (0) | 2021.01.15 |
-a 대 -e 옵션 인 경우 bash (0) | 2021.01.15 |
자바 스레드 재사용 (0) | 2021.01.15 |