C++11 템 플 릿 인자 의'오른쪽 값 참조'는 퍼 가기 참조 입 니까?
void f(int&& i);
그러나 다 그렇지 는 않 습 니 다.&&리 트 윗 인용 일 수도 있 습 니 다.
template<typename T>
void g(T&& obj);
'퍼 가기 인용'(forwarding reference)은'유 니 버 설 인용'(유 니 버 설 reference)이 라 고 불 렸 습 니 다.'유 니 버 설 레 퍼 런 스'는 왼쪽 값 을 퍼 가기 인용 에 연결 할 수 있 지만 오른쪽 값 을 참조 할 수 없습니다.
void f(int&& i) { }
template<typename T>
void g(T&& obj) { }
int main()
{
int n = 2;
f(1);
// f(n); // error
g(1);
g(n);
}
함수 의 인자 가 퍼 가기 참조 가 되 려 면 만족 해 야 합 니 다.
template<typename T>
void f(const T&&);
template<typename T>
void g(typename std::remove_reference<T>&&);
template<typename T>
class A
{
template<typename U>
void h(T&&, const U&);
};
다른 상황 은 auto&&변수 도 퍼 가기 참조 가 될 수 있 습 니 다.
auto&& vec = foo();
그래서 범위 for 순환 을 쓰 는 가장 좋 은 방법 은 auto&&:
std::vector<int> vec;
for (auto&& i : vec)
{
// ...
}
auto&&&오른쪽 에 있 는 목록 을 초기 화 하 는 예외 가 있 습 니 다.예 를 들 어 auto&l={1,2,3};이 변 수 는 std::initializerlist퍼 가기 인용 은 퍼 가기 에 쓰 인 다.리 트 윗 매개 변수 가 의도 되 었 을 때 만 리 트 윗 인용 T&&&를 쓰 는 것 이 좋 습 니 다.그렇지 않 으 면 const T&T&&&를 리 트 윗 으로 쓰 는 것 이 좋 습 니 다.(필요 하 다 면 T&도 쓸 수 있 고 자주 사용 하지 않 는 const T&&도 쓸 수 있 습 니 다.그 중에서 T 는 템 플 릿 매개 변수 가 아 닌 구체 적 인 유형 입 니 다).
퍼 가기 인용 을 전달 하려 면 std:forward 를 사용 해 야 합 니 다.
调用g有几种可能的参数:
- int i = 1; g(i);,T为int&,调用g(int&);
- const int j = 2; g(j);,T为const int&,调用g(const int&);
- int k = 3; g(std::move(k));或g(4);,T为int(不是int&&哦!),调用g(int&&)。
你也许会疑惑,为什么std::move不需要<T>而std::forward需要呢?这得从std::forward的签名说起:
template<typename T>
constexpr T&& forward(std::remove_reference_t<T>&) noexcept;
template<typename T>
constexpr T&& forward(std::remove_reference_t<T>&&) noexcept;
std::forward 를 호출 할 때 컴 파일 러 는 std::remove 에 따라 사용 할 수 없습니다.reference_t그러나 이 는 근본적으로 문 제 를 대답 하거나 새로운 문 제 를 더 끌 어 낼 수 있 는 것 이 아니다.왜 std:forward 의 매개 변 수 는 T&&&로 정의 되 지 않 습 니까?
이 유 는 간단 하 다.T&&는 T&,const T&,T&&와 const T&&(그리고 해당 하 는 volatile)를 모두 먹 어 버 리 고 T&&&가 있 으 면 T&를 써 도 소 용이 없다.
잠깐 만,T&&&인자 가 들 어 오 는 함수 가 T&&&와 일치 합 니까?
#include <iostream>
#include <utility>
void foo(int&)
{
std::cout << "int&" << std::endl;
}
void foo(const int&)
{
std::cout << "const int&" << std::endl;
}
void foo(int&&)
{
std::cout << "int&&" << std::endl;
}
void bar(int&& i)
{
foo(i);
}
int main()
{
int i;
bar(std::move(i));
}
아니 야!프로그램 출력 int&.함수 bar 에서 i 는 왼쪽 값 으로 int 의 오른쪽 값 참조 입 니 다.좀 더 직접적 으로 이름 이 있 기 때문에 왼쪽 값 입 니 다.따라서 std:forward 가 수 동 으로 지정 한 템 플 릿 인자 가 없 으 면 T&T&&를 구분 할 수 없습니다.그것 은'완벽 한 퍼 가기'가 아니 라'나 쁜 퍼 가기'가 될 것 입 니 다.
마지막 으로 std:forward 의 실현 을 분석 하고 다음 코드 는 libstdc++에서 나 옵 니 다.
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
{ return static_cast<_Tp&&>(__t); }
template<typename _Tp>
constexpr _Tp&&
forward(typename std::remove_reference<_Tp>::type&& __t) noexcept
{
static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"
" substituting _Tp is an lvalue reference type");
return static_cast<_Tp&&>(__t);
}
프로그래머 는 항상 Stack Overflow 에서 벽 에 부 딪 혀 야 뭔 가 를 배 울 수 있다.
여기 서 C++11 템 플 릿 매개 변수 에 대한'오른쪽 값 참조'가 리 트 윗 참조 인지 에 대한 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++11 오른쪽 값 참조 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
어디서나 먹을 수있는 C++ 소프트웨어 엔지니어가되기 위해아래의 책은 숙독하자. 테스트 리팩토링, 좋은 설계란 무엇인가를 배울 수 있습니다. 임베디드 분야의 예를 사용하고 있습니다만, 임베디드를 하지 않는 사람이라도 도움이 되는 내용입니다. C/C++ 언어의 어려운 점은 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.