다음 코드 :rvalue-reference 튜플에서 std :: get의 동작이 위험합니까?
#include <tuple>
int main()
{
auto f = []() -> decltype (auto)
{
return std::get<0> (std::make_tuple (0));
};
return f();
}
(조용히) 정의되지 않은 동작과 코드를 생성 - make_tuple
에 의해 반환되는 일시를 rvalue는 표준 : <을 얻을 통해 전파>하고 반환 형식 상 decltype (자동)를 통해. 그래서 범위를 벗어난 임시 참조를 반환합니다. 그것을 여기에서보십시오 https://godbolt.org/g/X1UhSw.
지금, decltype(auto)
을 잘못 사용했다고 주장 할 수 있습니다. 그러나 제네릭 코드 (튜플 유형이 std::tuple<Foo &>
일 수 있음)에서는 항상 사본을 만들고 싶지 않습니다. 정말 튜플에서 정확한 값이나 참조를 추출하고 싶습니다.
내 느낌 std::get
의이 오버로드는 위험하다입니다 : 튜플 요소에 좌변 참조를 전파하는 것은 아마 현명한입니다
template< std::size_t I, class... Types >
constexpr std::tuple_element_t<I, tuple<Types...> >&&
get(tuple<Types...>&& t) noexcept;
동안, 나는이를 rvalue 참조에 대한 보유하고 생각하지 않습니다.
나는 표준위원회가이를 매우 신중하게 생각했지만, 누구나 이것이 왜 최선의 선택이라고 생각하는지 설명 할 수 있을까요? 우리가 std::tuple{foo{}}
임시 것을 알고는 consume_tuple_first(std::tuple{foo{}})
표현의 전체 기간 동안 사는 것,이 경우
void consume(foo&&);
template <typename Tuple>
void consume_tuple_first(Tuple&& t)
{
consume(std::get<0>(std::forward<Tuple>(t)));
}
int main()
{
consume_tuple_first(std::tuple{foo{}});
}
:
* "rvalue references에 해당한다고 생각하지 않습니다."* - 'forward_as_tuple'이라면 가능합니다. 가치 범주를 보존하려고합니다. 또는 함수 반환 값에서 하나의 값을 추출하려는 경우 – StoryTeller
고마워,하지만 나는 그것이 가치 범주를 보존하고 있는지 정말로 모르겠다. 예를 들어'std :: tuple'을 반환하는 함수가 있고'std :: get <0>'을 호출하면 나는'int && '가 아닌 일반'int'를 얻을 것으로 기대합니다. 당신이 다른 것을 원할 때 구체적인 예를 들어 줄 수 있습니까? –
효과적인 구조화 된 바인딩에 필요한 'get'의 과부하가 아닙니까? –