올바른 전달을 보장하기 위해 std::forward를 사용하여 템플릿 인수 추론 비활성화
VS2010에서 std::forward 정의를 고려하세요.
template inline
_Ty&& forward(typename identity<_Ty>::type& _Arg)
{ // forward _Arg, given explicitly specified type parameter
return ((_Ty&&)_Arg);
}
ID 템플릿의 목적은 템플릿 인수 공제를 비활성화하는 것입니다. 이 시나리오에서 이것이 중요한 이유는 무엇입니까?
템플릿 인수 추론은 잘못된 유형 추론으로 이어질 수 있습니다. X 유형의 객체에 대한 rvalue 참조가 매개변수 유형 T&를 사용하여 템플릿 함수에 전달되면 템플릿 인수 추론은 T를 X로 추론하여 매개변수 유형 X&가 됩니다. 그러나 완벽한 전달을 위해 매개변수에는 이름이 있으므로 lvalue입니다. 따라서 std::forward에서 템플릿 인수 추론을 사용하면 추론된 매개변수 유형이 lvalue 참조 또는 const lvalue 참조가 됩니다.
template
T&& forward_with_deduction(T&& obj)
{
return static_cast다음 예시를 고려하세요.
void test(int&){}
void test(const int&){}
void test(int&&){}
template
void perfect_forwarder(T&& obj)
{
test(forward_with_deduction(obj));
}
int main()
{
int x;
const int& y(x);
int&& z = std::move(x);
test(forward_with_deduction(7)); // 7 is an int&&, correctly calls test(int&&)
test(forward_with_deduction(z)); // z is treated as an int&, calls test(int&)
// All the below call test(int&) or test(const int&) because in perfect_forwarder 'obj' is treated as
// an int& or const int& (because it is named) so T in forward_with_deduction is deduced as int&
// or const int&. The T&& in static_cast<T&&>(obj) then collapses to int& or const int& - 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));
}
이 예에서는 Perfect_forwarder의 매개변수가 이름 때문에 lvalue 또는 const lvalue 참조로 처리되기 때문에 완벽한 전달이 실패합니다. 이로 인해 Forward_with_deduction에서 잘못된 유형 추론이 발생하여 원하지 않는 static_cast 의미 체계가 발생합니다.
std::forward의 ID 템플릿을 사용하여 템플릿 인수 추론을 비활성화하면 std::forward가 항상 rvalue 참조를 반환합니다. lvalue와 rvalue의 완벽한 전달을 수정합니다.
부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.
Copyright© 2022 湘ICP备2022001581号-3