다양한 반환 유형을 가진 std :: array에 대한 recursive_transform

Oct 26 2020

이것은 다양한 반환 유형을 가진 std :: vector 에 대한 recursive_transform에 대한 후속 질문입니다 . G. Sliepen 덕분에 추가 리뷰 제안을 제공합니다. recursive_transform다양한 출력 유형과 다양한 컨테이너 유형 모두에서 더 일반적인 기능 을 달성하는 주제를 파헤친 후에도 여전히 간단한 해결책이 없습니다. 그러나 G. Sliepen의 대답 에 따라 std::vector, std::deque및 std::list컨테이너 유형의 경우가 해결 될 수 있습니다. 에 recursive_transform대한 추가 오버로드 기능 을 구현하려고합니다 std::array. 여기에 내 구현이 있습니다.

template<class T, std::size_t S, class F>
auto recursive_transform(std::array<T, S>& input, const F& f)
{
    using TransformedValueType = decltype(recursive_transform(*input.cbegin(), f));

    std::array<TransformedValueType, S> output;
    std::transform(input.cbegin(), input.cend(), output.begin(), 
        [f](auto& element)
        {
            return recursive_transform(element, f);
        }
    );
    return output;
}

테스트 사례 std::array:

//  std::array<int, 10> -> std::array<std::string, 10>
std::array<int, 10> test_array;
for (int i = 0; i < 10; i++)
{
    test_array[i] = 1;
}
auto recursive_transform_result5 = recursive_transform(
    test_array,
    [](int x)->std::string { return std::to_string(x); });                          //  For testing
std::cout << "string: " + recursive_transform_result5.at(0) << std::endl;

여기 Godbolt 링크가 있습니다. 에 대한 테스트 케이스를 포함하여이 링크 코드 std::vector, std::deque과 std::list.

모든 제안을 환영합니다.

요약 정보 :

  • 어떤 질문에 대한 후속 조치입니까?

    다양한 반환 유형을 가진 std :: vector에 대한 recursive_transform

  • 지난 질문 이후 코드에서 어떤 변화가 있었습니까?

    이전 버전의 recursive_transform함수 에서 처리 가능한 컨테이너 유형 은 std:vector입니다. 함께 G. Sliepen의 대답 이 취급이 컨테이너 유형 목록이 확장되고 std::vector, std::deque하고 std::list. 그런 다음 std::array여기서 처리하려고합니다 .

  • 새로운 리뷰가 요청되는 이유는 무엇입니까?

    이 버전의 recursive_transform함수에서는 언급 된 테스트 케이스에서 잘 작동하는 것 같습니다 std::array<int, 10> -> std::array<std::string, 10>. 그러나 std::array<std::array<int, 10>, 10> -> std::array<std::array<std::string, 10>, 10>(확장 성 향상!) 과 같은 더 복잡한 경우에는 몇 가지 문제 가 있습니다. 이에 대한 제안이나 가능한 아이디어가 있으면 알려주십시오.

답변

1 G.Sliepen Oct 26 2020 at 20:37

const일관되게 참조로 통과하는지 확인하십시오.

코드의 주요 문제는 std::array과부하가 const참조로 입력을 받도록 만들지 않았다는 것입니다 .

auto recursive_transform(std::array<T, S>& input, const F& f)

그냥 추가하십시오 const! 중첩 된 작업 과 함께이 Godbolt 링크 를 참조하십시오 std::array.

std::begin()및 사용 선호std::end()

당신은 단지 표준 라이브러리에서 컨테이너를 지원하려면,하지만 템플릿을 작성할 때, 사용하는 것을 선호 정말 중요하지 않습니다 std::begin()및 std::end()대신 ->begin()과 ->end(). 장점은 제공하지 않는 어딘가에서 비표준 컨테이너 begin()와 end()멤버 함수를 사용하는 경우 클래스 외부 std::begin()및 std::end()함수를 오버로드하여 해당 클래스에 반복기 지원을 추가 할 수 있다는 것입니다. 알고리즘 템플릿에서 사용하는 경우 알고리즘은 이러한 비표준 클래스도 지원합니다.