Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Item 24 - Universal Reference 와 Rvalue Reference를 구별하라 #5

Open
JayCheck opened this issue Sep 4, 2017 · 2 comments

Comments

@JayCheck
Copy link
Collaborator

JayCheck commented Sep 4, 2017

Item 24의 내용 중 아래와 같은 내용이 나옵니다.

Even the simple presence of a const qualifier is enough to disqualify a reference from being universal:

template<typename T> 
void f(const T&& param);         // param is an rvalue reference

그런데 이유는 전혀 나오지 않습니다.
저자는 단지 "Universal reference(== forwarding reference) 는 반드시 type deduction 이 있으면서 "T&&" 형태가 아니면 Universal reference 가 안된다" 라고만 설명하고 있습니다.
Scott mayers 의 다른 article

StackOverflow 에서도 동일한 의문을 제기하는 글이 있습니다.
https://stackoverflow.com/questions/38814939/why-adding-const-makes-the-universal-reference-as-rvalue
답변에 따르면 먼저 표준에는 forwarding reference 의 정의 자체가 "A forwarding reference is an rvalue reference to a cv-unqualified template parameter"로 const 가 없는 Rvalue reference 형태라고 되어 있습니다. 그리고 이렇게 한 이유는 const T&& 도 universal reference 로 허용하게 되면 rvalue 만 받고자 하는 함수 overloading 을 만들 수가 없기 때문이라고 설명하고 있습니다.

The problem is that we would have no way to overload a template function who takes only rvalue reference as parameter if both T && and const T && are allowed to use as forwarding references. – Carousel

  • 추후 업데이트 필요
@romandev
Copy link
Member

romandev commented Sep 7, 2017

시발.. 개장문의 글을 썼는데 브라우저 죽었네...

@romandev
Copy link
Member

romandev commented Sep 7, 2017

Universal Reference VS Forwarding Reference

Universal Reference라는 용어는 이 표준에 대한 제안 된 초기에 사용되던 이름이며, 최신 표준에서는 Forwarding Reference로 불리거나 불릴 예정이라고 합니다.

책에서 말하는 Forwarding Reference (a.k.a Universal Reference) [1]

하나의 참조가 보편 참조(Forwarding Reference)이려면 반드시 형식 연역(타입 추론)이 관여해야 한다. 그런데 이는 필요조건일 뿐 충분조건은 아니다. 참조 선언의 형태(form)도 정확해야 하는데, 그 형태는 상당히 제한적이다. 구체적으로 말해서 딱 "T&&"의 형태이어야 한다.

표준에서 말하는 Forwarding Reference [2]

A forwarding reference is an rvalue reference to a cv-unqualified template parameter.

즉, @JayChl님의 설명대로 const(or volatile)이 아닌 template parameter이 rvalue reference를 말합니다. 여기서 다소 혼란을 줄 수 있는 부분이 rvalue reference라는 말인데, 여기서의 rvalue reference란 아마도 rvalue 자체를 의미하는 것이 아니라 && rvalue reference 기호 자체를 의미함에 주의해야 합니다.

표준 제안서(?)에서 말하는 Forwarding Reference [3][4]

To the C++ programmer, a parameter of type C&& is always an rvalue reference—except when C is a template parameter type or auto, in which case it behaves very differently even though language-technically it is still an rvalue reference.

We intentionally overloaded the && syntax with this special case, but we did not give this special case a name. It needs a distinct name so that we can talk about it and teach it. This has already been discovered in the community, thanks to Scott Meyers in particular.

해석해보면, 결국, && (rvalue reference)를 그저 오버로딩(overloading)하여 재사용하였다는 것입니다. 즉, forwarding reference는 rvalue reference(기호가 아닌 의미상)와는 모양만 같을 뿐 전혀 다른 의미로 사용됩니다.

그렇다면 대체 "왜"라는 생각이 들 수 있는데, 추측컨데, 그것은 아마도 C++ 표준 커뮤니티의 특성이 아닌가 생각합니다. 이미 기존에도 이처럼 같은 키워드를 서로 다른 의미로 오버로딩하는 경우를 많이 찾을 수 있습니다. 대표적으로 static키워드가 있습니다. static의 경우 local variable에 사용되면 stack이 아닌 static 영역에 정의되는 효과를 볼 수 있습니다. 한편, global variable에 사용되면 static은 변수의 저장공간이 아닌 파일 scope을 internal link로 제한하는 한정자의 형태로 사용됩니다.

그럼.. 20000

[1] Modern Effective C++ (Item 24)
[2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf
[3] https://isocpp.org/files/papers/N4164.pdf
[4] https://isocpp.org/blog/2014/10/n4164

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants