Program Club

C ++ 17 : 튜플 압축을 풀 때 일부 멤버 만 유지

proclub 2020. 11. 21. 08:55
반응형

C ++ 17 : 튜플 압축을 풀 때 일부 멤버 만 유지


다음 메서드를 호출해야한다고 가정 해 보겠습니다.

std::tuple<int, int, int> foo();

C ++ 17에서는 함수를 호출하고 한 줄로 튜플을 풀 수 있습니다.

auto [a, b, c] = foo();

자, 어떻게에만 저장 진행할 수 bc및 폐기에 a?

현재 저는 두 가지 옵션 만 알고 있습니다.


1-자동 압축 해제시 더미 변수를 사용할 수 있습니다.

그러나 더미 변수는 사용되지 않고 경고가 발생하므로 경고를 조용히하고 싶다면 코드를 보는 것이 매우 불쾌 할 것입니다.

#pragma warning(push)
#pragma warning(disable:4101)
// ReSharper disable once CppDeclaratorNeverUsed
auto [_, b, c] = foo();
#pragma warning(pop)

2-전체 튜플을 저장하고 std::get필요한 유일한 변수에 대한 참조를 검색하는 데 사용할 수 있습니다. 코드는 덜 불쾌하지만 구문도 덜 간단합니다.

또한이 코드의 크기는 튜플에 유지하려는 새 값마다 한 줄씩 증가합니다.

auto tuple = foo();
int b = std::get<1>(tuple);
int c = std::get<2>(tuple);

튜플에서 일부 매개 변수 만 압축 해제하는 또 다른 간단한 방법이 있습니까?


또 다른 대안은 다음을 사용하는 것입니다 std::tie.

int b, c;
std::tie(std::ignore, b, c) = foo();

편집하다

의견에서 언급했듯이이 접근 방식에는 몇 가지 문제가 있습니다.

  • 유형 추론 불가능
  • 객체는 이전에 생성되어야하므로 기본 생성자가 사소한 경우가 아니면 좋은 대안이 아닙니다.

불행하게도 구조 바인딩이 명시 적으로 회원을 폐기 지원과 같은 속성을하지 않습니다 [[maybe_unused]]에 적용 할 수 없습니다 구조화 바인딩 (: 그에 대한 제안 거기 P0609 : "구조화 바인딩의 속성" ).

가능한 해결책은 다음과 같습니다.

auto [a, b, c] = foo();
(void) a; // unused

특정 인덱스 만 반환하는 도우미 함수를 작성할 수 있습니다 std::tuple.

template <size_t... Is, typename Tuple>
auto take_only(Tuple&& tuple) {
    using T = std::remove_reference_t<Tuple>;

    return std::tuple<std::tuple_element_t<Is, T>...>(
        std::get<Is>(std::forward<Tuple>(tuple))...);
}

auto [b, c] = take_only<1, 2>(foo());

또는 머리 나 무언가를 떨어 뜨립니다.

template <size_t... Is, typename Tuple>
auto drop_head_impl(Tuple&& tuple, std::index_sequence<0, Is...> ) {
    return take_only<Is...>(std::forward<Tuple>(tuple));
}

template <typename Tuple>
auto drop_head(Tuple&& tuple) {
    return drop_head_impl(std::forward<Tuple>(tuple),
        std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>());
}

auto [b, c] = drop_head(foo());

그러나 위의 구현에는 구조화 된 바인딩을 직접 사용하는 경우에는없는 수명 복잡성 문제가 거의 확실합니다. 여기에는 수명 연장이 없기 때문입니다.

그러니 Vittorio가 말한대로하십시오 .

auto [a, b, c] = foo();
(void)a;

MSVC는 이미 VS 15.7 Preview에서 이것을 수정 했습니다. 최종 15.7 릴리스는 몇 주 안에 사용할 수 있습니다. 이는 모든 주요 컴파일러의 최신 릴리스에서 지원하는 현재 로직이 다음과 같음을 의미합니다.

  • 구조화 된 바인딩 선언에서 구조화 된 바인딩 중 하나 이상이 사용되는 경우 동일한 선언의 다른 바인딩에 대해 "사용되지 않은 변수"경고가 발행되지 않습니다.
  • If none of the bindings in a structured binding declaration are used, it is possible to silence the warning by using the [[maybe_unused]] attribute:

    [[maybe_unused]] auto [a, b, c] = foo();

참고URL : https://stackoverflow.com/questions/50176315/c17-keep-only-some-members-when-tuple-unpacking

반응형