C++11 템 플 릿 인자 의'오른쪽 값 참조'는 퍼 가기 참조 입 니까?

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);
}

함수 의 인자 가 퍼 가기 참조 가 되 려 면 만족 해 야 합 니 다.
  • 매개 변수 유형 은 T&&이 고 const 나 volatile 이 없습니다
  • T 는 이 함수 의 템 플 릿 매개 변수 여야 합 니 다
  • 다시 말 하면 다음 함수 의 매개 변 수 는 퍼 가기 참조 가 아 닙 니 다.
    
    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는 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);
     }
    
    
  • 리 트 윗 인용 T&obj 바 인 딩 왼쪽 값 int&시 첫 번 째 리 트 윗 과 일치 합 니 다.Tp 즉 T 는 int&,반환 유형Tp&&는 int&(인용 접 기:&,&&,&&&모두 접 기&,&&&&만 접 기&&&로 접 기)
  • const int&동 리;
  • 바 인 딩 오른쪽 값 int&&를 참조 할 때 두 번 째 과부하 와 일치 합 니 다.Tp 는 int 이 고,반환 유형 은 int&&;입 니 다
  • const int&&&동 리..종합 적 으로 std:forward 는 완벽 하 게 전달 할 수 있 습 니 다.
    프로그래머 는 항상 Stack Overflow 에서 벽 에 부 딪 혀 야 뭔 가 를 배 울 수 있다.
    여기 서 C++11 템 플 릿 매개 변수 에 대한'오른쪽 값 참조'가 리 트 윗 참조 인지 에 대한 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 C++11 오른쪽 값 참조 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 많은 응원 바 랍 니 다!

    좋은 웹페이지 즐겨찾기