아닐 것 같지만 확인하고 싶습니다. 클래스 유형은 const Foo&&
어디에 사용 Foo
됩니까?
답변:
때때로 유용합니다. 초안 C ++ 0x 자체는 다음과 같이 몇 군데에서이를 사용합니다.
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
위의 두 오버로드는 다른 ref(T&)
및 cref(const T&)
함수가 rvalue에 바인딩되지 않도록합니다 (그렇지 않으면 가능함).
최신 정보
아쉽게도 공개적으로 사용할 수없는 공식 표준 N3290을 확인 했으며 20.8 Function 객체 [function.objects] / p2에 있습니다.
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
그런 다음 공개적으로 사용 가능한 최신 C ++ 11 이후 초안 인 N3485 를 확인했으며 20.8 함수 개체 [function.objects] / p2에서 여전히 다음과 같이 말합니다.
template <class T> void ref(const T&&) = delete;
template <class T> void cref(const T&&) = delete;
const T&&
가 사용됩니까?
const T&&
하면 누군가 어리석게 형식의 명시 적 템플릿 인수를 사용하는 것을 방지 할 수 ref<const A&>(...)
있습니다. 끔찍한 주장은 아니지만 const T&&
오버 비용 T&&
은 매우 적습니다.
const rvalue 참조 (for가 =delete
아님) 를 얻는 의미는 다음과 같은 의미입니다 .
다음 사용 사례 수 있었다 이럴위한 좋은 사용 사례 를 const를 rvalue 참조 언어가이 방법을 (참조 걸릴하지 않기로 결정하지만, 원래의 SO 게시물을 ).
일반적으로 사용하는 것이 좋습니다 것 make_unique
하고 make_shared
있지만, 모두 unique_ptr
와 shared_ptr
원시 포인터로 구성 될 수있다. 두 생성자 모두 값으로 포인터를 가져 와서 복사합니다. 둘 다 생성자에서 전달 된 원래 포인터의 연속 사용을 허용합니다 (예 : 방지하지 마십시오 ).
다음 코드는 double free로 컴파일되고 결과를 얻습니다 .
int* ptr = new int(9);
std::unique_ptr<int> p { ptr };
// we forgot that ptr is already being managed
delete ptr;
모두 unique_ptr
와 shared_ptr
그 관련 생성자가 원시 포인터를 얻을 것으로 예상한다면 위를 방지 할 수 CONST를 rvalue로 에 대한 예 unique_ptr
:
unique_ptr(T* const&& p) : ptr{p} {}
이 경우 위 의 이중 자유 코드는 컴파일되지 않지만 다음은 다음과 같습니다.
std::unique_ptr<int> p1 { std::move(ptr) }; // more verbose: user moves ownership
std::unique_ptr<int> p2 { new int(7) }; // ok, rvalue
참고 ptr
잠재적 인 버그가 완전히 사라되지 않도록 아직도 후 사용할 수는 이동되었다. 그러나 사용자가 std::move
이러한 버그 를 호출해야하는 경우 일반적인 규칙에 해당합니다. 이동 된 리소스를 사용하지 마십시오.
다음과 같이 질문 할 수 있습니다. OK,하지만 왜 T*
const&& p
입니까?
그 이유는 간단 합니다. unique_ptr
const pointer에서 생성을 허용하기 때문입니다 . 그 기억 CONST의를 rvalue 참조가 단지보다 제네릭 를 rvalue 참조 가 모두 허용으로 const
와 non-const
. 따라서 다음을 허용 할 수 있습니다.
int* const ptr = new int(9);
auto p = std::unique_ptr<int> { std::move(ptr) };
rvalue 참조 (컴파일 오류 : const rvalue 를 rvalue에 바인딩 할 수 없음) 만 기대한다면이 방법은 진행되지 않습니다 .
어쨌든, 이런 제안을하기에는 너무 늦었습니다. 그러나이 아이디어는 const 에 대한 rvalue 참조 의 합리적인 사용법을 제시합니다 .
그것들은 허용되고 심지어 함수는를 기준으로 순위가 매겨 const
지지만에서 참조하는 const 객체에서 이동할 수 없기 const Foo&&
때문에 유용하지 않습니다.
const T&, T&, const T&&, T&&
std :: ref 외에도 표준 라이브러리는 동일한 목적으로 std :: as_const의 const rvalue 참조를 사용합니다 .
template <class T>
void as_const(const T&&) = delete;
래핑 된 값을 가져올 때 std :: optional 에서 반환 값으로도 사용됩니다 .
constexpr const T&& operator*() const&&;
constexpr const T&& value() const &&;
뿐만 아니라 std :: get :
template <class T, class... Types>
constexpr const T&& get(const std::variant<Types...>&& v);
template< class T, class... Types >
constexpr const T&& get(const tuple<Types...>&& t) noexcept;
이는 아마도 래핑 된 값에 액세스 할 때 래퍼의 일관성뿐 아니라 값 범주를 유지하기위한 것입니다.
이것은 const rvalue ref-qualified 함수가 래핑 된 객체에서 호출 될 수 있는지 여부에 차이를 만듭니다. 즉, const rvalue ref 한정 함수의 용도를 알지 못합니다.
이것이 직접적으로 유용 할 것이라고 생각할 수는 없지만 간접적으로 사용될 수 있습니다.
template<class T>
void f(T const &x) {
cout << "lvalue";
}
template<class T>
void f(T &&x) {
cout << "rvalue";
}
template<class T>
void g(T &x) {
f(T());
}
template<class T>
void h(T const &x) {
g(x);
}
g 의 T 는 T const이므로 f 's x는 T const &&입니다.
이로 인해 f (객체를 이동하거나 사용하려고 할 때) 에 comile 오류가 발생할 가능성이 있지만 f 는 rvalue-ref를 가져 와서 rvalue를 수정하지 않고 lvalue에서 호출 할 수 없도록 할 수 있습니다 (너무 단순한 위의 예).
const&&
이유를 밝히지 않지만 매우 중요하다고 말합니다 . youtube.com/watch?v=JhgWFYfdIho#t=54m20s