programing

이 두 개의 고차 함수 정의 사이에 차이점이 있습니까?

telebox 2023. 6. 21. 22:30
반응형

이 두 개의 고차 함수 정의 사이에 차이점이 있습니까?

4개의 주요 문구 사이에 차이점이 있습니까?저는 apply2(&func)만 말이 된다고 생각합니다.그러나 4개 모두 동일한 값을 반환합니다.

int func(void) 
{
    return 1;
}

int apply1( int f1(void) )
{
    return f1();
}

int apply2( int (*f1) (void) ) 
{
    return f1();
}

int main() 
{
    apply1(func); 
    apply1(&func);
    apply2(func);
    apply2(&func);

    return 0;
}

먼저, 함수 포인터는 어렵습니다.어떤 함수를 다른 함수에 매개 변수로 전달할 수 있다고 생각하는 것은 재귀를 이해하는 것과 유사한 마음의 동요를 필요로 합니다.처음에는 이해하지 못하겠지만, 갑자기 뇌에 이해의 홍수문이 열리고 깨달음을 얻는 것과 같습니다.

그러나 C와 C++에서 매개 변수로 함수를 전달하는 규칙을 알아야 합니다.이러한 언어에서는 기능이 1등 시민이 아니기 때문에 기능으로 할 수 있는 작업에 많은 제약이 있습니다.

구문

함수 포인터 구문이 조금 못생겼습니다.기본 해부학적 구조는[return type] (*[name])([argument list])주변 괄호*name는 함수 포인터와 포인터를 반환하는 함수 사이를 명확하게 구분하는 데 필요합니다.

// not function pointers: * not grouped to function name
int x(); // function that returns an int
int* x(); // function that returns an int*
int *x(); // also a function that returns an int*, spaces don't matter

// function pointers: * grouped to function name
int (*x)(); // pointer to a function that returns an int
int* (*x)(); // pointer to a function that returns an int*

붕괴

매개 변수로 전달하는 측면에서 함수는 배열과 거의 동일하게 동작합니다.통과하면 포인터로 바뀝니다.비교:

void Foo(int bar[4]); // equivalent to: void Foo(int* bar)
void Bar(int baz()); // equivalent to: void Bar(int (*baz)())

이는 단순히 함수와 어레이를 할당할 수 없고 복사할 수 없기 때문입니다.

int foo[4];
int bar[4] = foo; // invalid

int foo();
int bar() = foo; // invalid

따라서 이들을 함수 매개변수로 전달하는 유일한 방법은 해당 매개변수를 복사하는 대신 주소를 전달하는 것입니다. (이것은 배열에서는 논쟁의 여지가 있지만, 그렇게 작동합니다.)이러한 "값"이 매개 변수로 전달될 때 포인터로 변환된다는 사실을 "쇠퇴"라고 합니다.

이 두 프로토타입은 호환되며(즉, 동일한 기능을 의미하며, 서로 다른 과부하가 아닙니다), 따라서 두 프로토타입 사이에는 차이가 없습니다.

int foo(void bar());
int foo(void (*bar)());

시각적인 측면은 차치하고, 그 두 선언 사이에는 전혀 차이가 없습니다.두 함수 모두 함수 포인터를 사용할 수 있습니다. 함수 포인터의 모양과 모양에 관계없이 함수 포인터는 감쇠로 인해 사용할 수 있습니다.그러나, 붕괴는 종종 불쾌하고 혼란스러운 것으로 여겨지기 때문에, 대부분의 개발자들은 함수 포인터를 명시적으로 요청하는 것을 선호할 것입니다(그리고 많은 개발자들은 함수 유형이 붕괴될 수 있다는 것조차 알지 못합니다).

암시적 변환

이제 함수를 매개 변수로 전달합니다.이것은 단순히 붕괴의 결과입니다. 함수는 암시적으로 함수 포인터 유형으로 변환되어야 합니다.이것은 함수 포인터가 필요한 곳에 함수를 전달할 수 있다는 것을 의미하며 컴파일러는 그 주소를 얻을 것입니다.이러한 목적을 위해 다시 한 번 다음과 같습니다.

int foo();
int (*bar)() = foo; // the compiler implicitly assigns the address of foo to bar
int (*baz)() = &foo; // you explicitly assign the address of foo to baz

이 두 가지 설명을 결합하면 네 가지 함수 호출이 모두 같다는 것을 알게 될 것입니다. apply1그리고.apply2 다 변수를 합니다(" 다 동 한허모다니용합를수둘유형의일(다▁both니▁(합둘"()).int (*)(void) )에, 에 대해서는 명확하지 않습니다.apply1 리고함 호때할출로 때.func&func컴파일러는 암시적으로 당신을 위해 주소를 가져가고 그것을 동등하게 만듭니다.&func.


다음은 질문의 범위를 벗어난 내용이지만 앞 부분을 자세히 설명하고 있고, 좀 깔끔하다고 생각합니다.

함수 참조 [C++ 전용]

잘 알려지지 않은 사실이지만 배열 및 함수에 대한 참조를 전달할 수도 있습니다. 이 경우에는 붕괴가 발생하지 않습니다.다음과 같이:

void Foo(int (&bar)[4]); // NOT equivalent to void Foo(int* bar)
void Bar(int (&baz)()); // NOT equivalent to void Bar(int (*baz)())

이 시나리오에서는 포인터 유형과 참조 유형 간에 암묵적인 변환이 없으므로 연산자의 주소를 사용할 수 없습니다.부패를 물리치는 것은 일반적으로 좋은 것으로 여겨지는데, 부패는 종종 혼란스럽기 때문입니다.

int baz();
Bar(baz); // valid
Bar(&baz); // INVALID

함수 참조는 일반 참조와 동일한 규칙을 따릅니다. 정의 시에만 할당할 수 있으며 null일 수 없습니다.

유형ef

다음을 사용하여 함수 포인터를 덜 못생기게 만들 수 있습니다.typedef.

typedef int (*X)();
X func; // func is a pointer to a function that returns an int

당신이 그것을 꺼내면 더 흥미로워집니다.(*)표시된 항목:

typedef int X();
X* func; // func is a function pointer
X& func; // func is a function reference [C++ only]
X func; // func is a function declaration (!!)

의 경우에는, 의경우는에후자,는,X func;다음과 같은 선언문에 해당합니다.int func();모두를 혼란스럽게 하고 싶지 않다면 집에서 이런 짓을 하지 마세요.

decltype [해당].이를 만듭니다 [C++만 해당]

함수와 함수 포인터 사이의 또 다른 흥미로운 차이는 다음의 사용과 함께 발생합니다.decltype.decltype익스프레스의 유형을 "수정"합니다.이 구성의 경우 다음과 같은 차이가 있습니다.function그리고.&function:

int bar();
decltype(bar); // type is int ()
decltype(&bar); // type is int (*)()

이 차이는 템플릿 매개 변수로 유형을 전달하려는 경우 특히 중요합니다.std::unique_ptr.

std::unique_ptr<void, decltype(free)> foo; // INVALID
std::unique_ptr<void, decltype(&free)> foo; // valid

. 첫 는 " 번는다인스필스함드않다습니유하지첫효하"의 인스턴스 를 생성하려고 하기 입니다.unique_ptr.

언급URL : https://stackoverflow.com/questions/18626080/are-there-any-differences-between-these-two-higher-order-function-definitions

반응형