>백엔드 개발 >C++ >std::forward가 ID 템플릿을 사용하여 템플릿 인수 공제를 비활성화하는 이유는 무엇입니까?

std::forward가 ID 템플릿을 사용하여 템플릿 인수 공제를 비활성화하는 이유는 무엇입니까?

Susan Sarandon
Susan Sarandon원래의
2024-11-09 09:34:02683검색

Why does std::forward use the identity template to disable template argument deduction?

올바른 전달을 보장하기 위해 std::forward를 사용하여 템플릿 인수 추론 비활성화

VS2010에서 std::forward 정의를 고려하세요.

<code class="cpp">template<class _Ty> inline
_Ty&amp;&amp; forward(typename identity<_Ty>::type&amp; _Arg)
{   // forward _Arg, given explicitly specified type parameter
    return ((_Ty&amp;&amp;)_Arg);
}</code>

ID 템플릿의 목적은 템플릿을 비활성화하는 것입니다. 인수 공제. 이 시나리오에서 이것이 중요한 이유는 무엇입니까?

템플릿 인수 추론은 잘못된 유형 추론으로 이어질 수 있습니다. X 유형의 객체에 대한 rvalue 참조가 매개변수 유형 T&를 사용하여 템플릿 함수에 전달되면 템플릿 인수 추론은 T를 X로 추론하여 매개변수 유형 X&가 됩니다. 그러나 완벽한 전달을 위해 매개변수에는 이름이 있으므로 lvalue입니다. 따라서 std::forward에서 템플릿 인수 추론을 사용하면 추론된 매개변수 유형이 lvalue 참조 또는 const lvalue 참조가 됩니다.

<code class="cpp">template<typename T>
T&amp;&amp; forward_with_deduction(T&amp;&amp; obj)
{
    return static_cast<T&amp;&amp;>(obj);
}</code>

다음 예를 고려하세요.

<code class="cpp">void test(int&amp;){}
void test(const int&amp;){}
void test(int&amp;&amp;){}

template<typename T>
void perfect_forwarder(T&amp;&amp; obj)
{
    test(forward_with_deduction(obj));
}

int main()
{
    int x;
    const int&amp; y(x);
    int&amp;&amp; z = std::move(x);

    test(forward_with_deduction(7));    //  7 is an int&amp;&amp;, correctly calls test(int&amp;&amp;)
    test(forward_with_deduction(z));    //  z is treated as an int&amp;, calls test(int&amp;)

    //  All the below call test(int&amp;) or test(const int&amp;) because in perfect_forwarder 'obj' is treated as
    //  an int&amp; or const int&amp; (because it is named) so T in forward_with_deduction is deduced as int&amp; 
    //  or const int&amp;. The T&amp;&amp; in static_cast<T&amp;&amp;>(obj) then collapses to int&amp; or const int&amp; - which is not what 
    //  we want in the bottom two cases.
    perfect_forwarder(x);           
    perfect_forwarder(y);           
    perfect_forwarder(std::move(x));
    perfect_forwarder(std::move(y));
}</code>

이 예에서는 Perfect_forwarder의 매개변수가 이름 때문에 lvalue 또는 const lvalue 참조로 처리되기 때문에 완벽한 전달이 실패합니다. 이로 인해 Forward_with_deduction에서 잘못된 유형 추론이 발생하여 원하지 않는 static_cast 의미 체계가 발생합니다.

std::forward의 ID 템플릿을 사용하여 템플릿 인수 추론을 비활성화하면 std::forward가 항상 rvalue 참조를 반환합니다. lvalue와 rvalue의 완벽한 전달을 수정하세요.

위 내용은 std::forward가 ID 템플릿을 사용하여 템플릿 인수 공제를 비활성화하는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.