2016-11-26 7 views
17

의 구분은 스콧 마이어스에 의해이 예에서 충분히 명확되었다 : 우리는, 따라서 A 경우 추론 될 상황있을 때전달 참조입니까? 를 rvalue 참조 및 전달 참조 사이

Widget&& var1 = someWidget;  // here, “&&” means rvalue reference (1) 

auto&& var2 = var1;    // here, “&&” does not mean rvalue reference (2) 

template<typename T> 
void f(std::vector<T>&& param); // here, “&&” means rvalue reference (3) 

template<typename T> 
void f(T&& param);    // here, “&&”does not mean rvalue reference (4) 

는 본질적으로 차이가 발생 (3) 명시 적으로 언급 우리가 (0)은 vector<...>&&이고 (4)의 경우 T은 "가치 범주"로 범주화 된 (참조 축소 규칙 적용 후).

그러나 좀 더 복잡한 패턴 일치는 어떻게됩니까? 예를 들어 다음과 같은 경우를 보자

template <template <class...> class Tuple, class... Ts> 
void f(Tuple<Ts...>&& arg) 
{ 

} 

&& 여기에 무엇을 의미합니까?

+1

Deducible 컨텍스트가 중요하지 않습니다. (3)과 (4)는 둘 다 연역적이다. – Oktalist

답변

14

마지막 예에서 arg은 값이있는 참조입니다.

전송 기준은

Tuple<Ts...> 템플릿 매개하지 않는 CV-비정규 템플릿 파라미터 r- 수치로 기준이다.

([temp.deduct.call]에서 표창.)

9

그것은 r- 수치 참조 아닌 착신 기준이다.

template<typename... Ts> 
struct foo {}; 

//f function definition 

int main() { 
    foo<int, double> bar; 
    f(bar); // fails! Cannot bind lvalue to rvalue reference 
    f(foo<int, double>{}); // ok, rvalue is passed 
} 
1

개념 전달 참조가되지 않습니다 :

확인하는 가장 쉬운 방법은 실패가 아닌 경우 경우, 전달 참조, 다음이를 rvalue 참조는, 좌변을 통과하는 것입니다 표준 개념이라면, 그것을 볼 때 그것을 인식하는 것이 유용 할 것이지만, 당신이 그것을 정확하게 이해하고 다루기를 원한다면 참조 계산을 이해해야 만합니다.

전달 참조의 개념 뒤에 무엇

가 기준 산술 (내가 메이어의 책은 또한 대한 장을 가지고 있다고 생각합니다) :

  • & & & & = & &
  • & & & = &
  • & & & = &
  • & & = &

의이 같은 상황에서 전달 참조

template<class T> 
void foo(T&&); 
//... 
const int i=42; 
foo(i); // the compiler will defines T = const int & 
     //   T&& = const int & && = const int & 
     // => the compiler instantiates void foo<const int &>(const int &); 
foo(6*7);// the compiler will defines T = int 
     //   T&& = int && 
     // the compiler instantiates void foo<int>(int &&); 

와 컴파일러 템플릿 유형 공제를 시뮬레이션하자, 템플릿 foo는의 인스턴스화 할 수 기능을 생산 lvalue reference 또는 인수를 취하는 함수에 의해 인수를 취한다. rvalue reference : 전달 참조는이다. 템플릿 형식 공제에 따라 0 값 참조 또는 1 값 참조 그것은 이러한 상황에서, 매개 변수는 좌변으로 또는가 xValue로 중 하나를 통과해야한다 있기 때문에이 같은 이름, 당신은 함수가 선언하면이 T&& std::forward<T>(T&& a)

의 작업입니다 :

template<class T> 
void foo(ATemplateClass<T> && a); 

컴파일러가 T에 대해 추론 한 형식이 무엇이든 관계없이 rvalue 참조 매개 변수를 가져옵니다.

+0

샘플을 확인 하시겠습니까? 나는 foo (42)와 foo (6 * 7)가 같은 보트에 있다고 믿는다 : https://godbolt.org/g/jOEK9b – RTempete

+0

@RTempete 포스트의 그 부분은 틀린 것으로 보인다. 'int &&'로 추론합니다 - 같은 것이지'const'가 아닙니다. Oliv이 왜 "const"이어야하는지, 그리고/또는 (-O0'에서조차도 사소하고 최적화 된) 표현이 포함되는지 여부에 따라 약간의 차이가 있어야한다고 생각하는 이유를 설명하면 훨씬 더 많을 것입니다 유능한. –

+0

죄송합니다. 예문 코드에는 두 가지 오류가 있습니다. f (42) -> r 값 참조 및 f (6 * 7)도 있습니다. – Oliv