>백엔드 개발 >C++ >Variadic 템플릿을 사용하여 C 11에서 `std::tuple`을 예쁘게 인쇄하는 방법은 무엇입니까?

Variadic 템플릿을 사용하여 C 11에서 `std::tuple`을 예쁘게 인쇄하는 방법은 무엇입니까?

Barbara Streisand
Barbara Streisand원래의
2024-11-07 17:44:03831검색

How to Pretty-Print `std::tuple` in C  11 Using Variadic Templates?

예쁜 인쇄 std::tuple

이 기사는 예쁜 인쇄 STL 컨테이너에 대한 이전 논의의 연속이며, 여기서 우아하고 일반적인 솔루션을 개발했습니다. 이 작업입니다.

문제 설명

이 확장에서는 특히 C 11에 맞게 조정된 가변 템플릿을 사용하여 std::tuple 개체에 대한 예쁜 인쇄 기능을 포함하는 것을 목표로 합니다. . std::pair에 대한 이전 예에서 영감을 받아 튜플에 대한 유사한 구성을 찾습니다. 원하는 동작은 다음과 같습니다.

auto a = std::make_tuple(5, "Hello", -0.1);
std::cout << a << std::endl; // prints: (5, "Hello", -0.1)

또한 다양한 문자 유형 및 사용자 정의 가능한 쌍 구분 기호 지원을 포함하여 이전 질문과 동일한 수준의 일반성을 통합하는 것을 목표로 합니다.

솔루션

인덱스 기반 접근 방식을 활용하면 다음 코드 조각을 사용하여 솔루션을 구성할 수 있습니다.

namespace aux{
template<std::size_t... Is> struct seq{};

template<std::size_t N, std::size_t... Is>
struct gen_seq : gen_seq<N-1, N-1, Is...>{};

template<std::size_t... Is>
struct gen_seq<0, Is...> : seq<Is...>{};

template<class Ch, class Tr, class Tuple, std::size_t... Is>
void print_tuple(std::basic_ostream<Ch,Tr>& os, Tuple const& t, seq<Is...>)
{
  using swallow = int[];
  (void)swallow{0, (void(
    os << (Is == 0? "" : ", ") << std::get<Is>(t)
  ), 0)...};
}
}

template<class Ch, class Tr, class... Args>
auto operator<<(std::basic_ostream<Ch, Tr>& os, std::tuple<Args...> const& t)
    -> std::basic_ostream<Ch, Tr>&
{
  os << "(";
  aux::print_tuple(os, t, aux::gen_seq<sizeof...(Args)>()
);
  return os << ")";
}

구분 기호 사용자 정의를 위해 다음 부분을 추가할 수 있습니다. 전문화:

// Delimiters for tuple
template<class... Args>
struct delimiters<std::tuple<Args...>, char> {
  static const delimiters_values<char> values;
};

template<class... Args>
const delimiters_values<char> delimiters<std::tuple<Args...>, char>::values =
    { "(", ", ", ")" };

template<class... Args>
struct delimiters<std::tuple<Args...>, wchar_t> {
  static const delimiters_values<wchar_t> values;
};

template<class... Args>
const delimiters_values<wchar_t> delimiters<
    std::tuple<Args...>, wchar_t
>::values = { L"(", L", ", L")" };

이러한 수정을 통해 연산자<< print_tuple 함수를 업데이트하여 구분 기호 사용자 정의를 통합할 수 있습니다:

template<class Ch, class Tr, class Tuple, std::size_t... Is>
void print_tuple(std::basic_ostream<Ch, Tr>& os, Tuple const& t, seq<Is...>)
{
  using swallow = int[];
  char const* delim = delimiters<Tuple, Ch>::values.delimiter;
  if(!delim) delim = "";
  (void)swallow{0, (void(
    os << (Is == 0? "" : delim) << std::get<Is>(t)
  ), 0)...};
}
template<class Ch, class Tr, class... Args>
auto operator<<(std::basic_ostream<Ch, Tr>& os, std::tuple<Args...> const& t)
    -> std::basic_ostream<Ch, Tr>&
{
  typedef std::tuple<Args...> tuple_t;
  if(delimiters<tuple_t, Ch>::values.prefix != 0)
    os << delimiters<tuple_t,char>::values.prefix;

  print_tuple(os, t, aux::gen_seq<sizeof...(Args)>()
);

  if(delimiters<tuple_t, Ch>::values.postfix != 0)
    os << delimiters<tuple_t,char>::values.postfix;

  return os;
}

위 내용은 Variadic 템플릿을 사용하여 C 11에서 `std::tuple`을 예쁘게 인쇄하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.