> 백엔드 개발 > C++ > 본문

`std::function`의 템플릿 인수(서명)가 해당 유형의 일부입니까?

Patricia Arquette
풀어 주다: 2024-11-08 19:50:02
원래의
890명이 탐색했습니다.

Is the Template Argument (Signature) of `std::function` Part of its Type?

std::Function의 서명 및 유형 모호성

개요

C에서 std::function은 호출 가능한 객체를 나타내는 템플릿 클래스입니다. . 함수를 인수로 전달하고 데이터 구조에 저장하는 유연한 방법을 제공합니다. 그러나 std::function의 템플릿 인수(서명)가 해당 유형의 일부인지 여부와 관련하여 일반적인 혼란의 원인이 발생합니다. 이 기사에서는 이 모호성에 대해 자세히 알아보고 잠재적인 해결책을 모색합니다.

문제

모호성은 함수의 여러 오버로드가 서로 다른 시그니처의 매개변수를 허용하지만 둘 다 동일한 유형에서 구성될 때 발생합니다. , 함수 포인터나 람다와 같은 것입니다. 다음 코드 조각을 고려하세요.

<code class="cpp">#include <functional>

using namespace std;

int a(const function<int ()>& amp;f)
{
    return f();
}

int a(const function<int (int)>& amp;f)
{
    return f(0);
}

int x() { return 22; }

int y(int) { return 44; }

int main()
{
    a(x);  // Call is ambiguous.
    a(y);  // Call is ambiguous.

    a((function<int ()>&)x);    // Works.
    a((function<int (int)>&)y); // Works.

    return 0;
}</code>
로그인 후 복사

이 예에서 a 함수는 function 유형의 함수 포인터 중 하나를 허용하도록 오버로드됩니다. 또는 함수. 서로 다른 시그니처를 갖는 함수 포인터인 x 또는 y를 사용하여 a를 호출하면 컴파일러는 어떤 오버로드를 선택할지 결정할 수 없어 모호성이 발생합니다.

모호성의 원인

이 모호성은 다음에서 비롯됩니다. std::function은 유형 삭제를 사용하므로 다양한 유형의 함수를 저장하고 호출할 수 있습니다. std::function의 템플릿 인수(서명)는 호출 가능 유형을 지정하는 자리 표시자 역할을 하지만 생성 중에는 엄격하게 적용되지 않습니다.

예를 들어 std::function의 생성자는 모든 유형을 허용할 수 있습니다. 서명이 템플릿 인수와 일치하지 않더라도 호출 가능한 객체로 변환될 수 있습니다. 이러한 구성의 유연성은 여러 오버로드가 느슨하게 구성 가능한 유형을 허용할 때 모호성을 초래합니다.

모호함 회피

모호성을 해결하려면 명시적 캐스팅을 사용하여 함수 지점에서 원하는 시그니처를 지정할 수 있습니다. 기도. 이렇게 하면 컴파일러가 캐스트 유형을 기반으로 올바른 오버로드를 식별할 수 있습니다. 위의 예에서는 호출을 명확하게 하기 위해 다음 캐스트를 추가할 수 있습니다.

<code class="cpp">a((function<int ()>&)x);  // Disambiguate as function<int ()>
a((function<int (int)>&)y); // Disambiguate as function<int (int)></code>
로그인 후 복사

또는 적절한 유형의 함수 객체를 생성하여 함수에 직접 전달할 수 있습니다.

<code class="cpp">function<int ()> fx = x;
function<int (int)> fy = y;
a(fx);  // No ambiguity
a(fy);  // No ambiguity</code>
로그인 후 복사

마지막으로, 템플릿 메타프로그래밍 기술을 사용하여 다양한 시그니처에 대한 특수 기능을 생성할 수 있으므로 명시적인 캐스팅이 필요하지 않습니다. 이 접근 방식은 더욱 우아하고 유형이 안전한 솔루션을 제공합니다.

결론

std::function의 시그니처는 호출 가능 유형을 지정하기 위한 자리 표시자 역할을 하지만 생성 중에 유형 일치를 엄격하게 적용하지는 않습니다. 이러한 유연성으로 인해 여러 오버로드가 느슨하게 생성 가능한 형식을 허용하는 경우 모호성이 발생할 수 있습니다. 개발자는 함수 객체나 템플릿 메타프로그래밍과 같은 명시적 캐스팅이나 대체 접근 방식을 사용하여 함수 호출을 명확하게 하고 올바른 오버로드가 선택되었는지 확인할 수 있습니다.

위 내용은 `std::function`의 템플릿 인수(서명)가 해당 유형의 일부입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿