다양한 반환 유형을 가진 std :: array에 대한 recursive_transform
이것은 다양한 반환 유형을 가진 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>(확장 성 향상!) 과 같은 더 복잡한 경우에는 몇 가지 문제 가 있습니다. 이에 대한 제안이나 가능한 아이디어가 있으면 알려주십시오.
답변
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()함수를 오버로드하여 해당 클래스에 반복기 지원을 추가 할 수 있다는 것입니다. 알고리즘 템플릿에서 사용하는 경우 알고리즘은 이러한 비표준 클래스도 지원합니다.