types_apply_result

types_apply_result (호출 결과 타입 추론)

std::apply_result<type_traits> 헤더에 정의된 클래스 템플릿이에요. 주어진 함수 객체(Fn)와 튜플(Tuple)을 사용해 INVOKE 표현식의 반환 타입을 추론하는 데 사용돼요. C++26부터 사용할 수 있어요.

출처: cppreference

본문

개요

/*ELEMS-OF*/(T)std::get<N>(std::declval<T>())의 매개변수 팩이에요. 여기서 N은 std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<T>>>로 표기되는 std::index_sequence 특수화의 std::size_t 템플릿 인자 팩이에요.

tuple-like<Tuple>이 참이고, /*INVOKE*/(std::declval<Fn>(), /*ELEMS-OF*/(Tuple)...) 표현식이 비평가 피연산자(unevaluated operand)로 취급될 때 유효하다면, 멤버 typedef typedecltype(/*INVOKE*/(declval<Fn>(), /*ELEMS-OF*/(Tuple)...)) 타입을 나타내요. 그렇지 않으면 멤버 타입이 존재하지 않아요.

접근 검사는 Fn과 Tuple과 무관한 맥락에서 수행되는 것처럼 처리돼요. 표현식의 즉시 맥락(immediate context)의 유효성만 고려돼요.

표현식의 컴파일은 클래스 템플릿 특수화와 함수 템플릿 특수화의 인스턴스화, 암시적으로 정의된 함수의 생성 등과 같은 부작용을 초래할 수 있어요. 이러한 부작용은 "즉시 맥락"에 속하지 않으며 프로그램이 ill-formed가 될 수 있어요.

Fn이나 Tuple이 완전 타입(complete type)이 아니거나, (cv 한정 가능한) void이거나, 바운드가 알려지지 않은 배열이면 동작이 정의되지 않아요.

위 템플릿의 인스턴스화가 불완전 타입에 직간접적으로 의존하고, 해당 타입이 가상으로 완성된다면 다른 결과를 산출할 수 있는 경우, 동작은 정의되지 않아요.

이 페이지에 설명된 템플릿 중 하나에 대해 프로그램이 특수화를 추가하면 동작이 정의되지 않아요.

멤버 타입

멤버 타입 설명
type Callable 타입 Fn이 Tuple에 주어진 인자들로 호출될 때의 반환 타입이에요. Fn이 비평가 맥락에서 Tuple의 인자들로 호출될 수 있는 경우에만 정의돼요.

헬퍼 타입

template < class Fn , class Tuple > using apply_result_t = apply_result < Fn , Tuple >:: type ; (since C++26)

가능한 구현

namespace detail
{
template<std::size_t I, class T>
using element_at = decltype(std::get<I>(std::declval<T>()));

template<class Fn, class T, std::size_t ... I>
constexpr auto apply_impl(Fn&& f, T&& t, std::index_sequence<I...>)
    noexcept (std::is_nothrow_invocable_v<Fn, element_at<I, T >...>)
        -> std::invoke_result_t<Fn, element_at<I, T>...>
{
    return std::invoke(std::forward<Fn>(f), std::get<I>(std::forward<T>(t))...);
}

template<class Fn, class Tuple>
using apply_result_t = decltype(apply_impl(
    std::declval<Fn>(),
    std::declval<Tuple>(),
    std::make_index_sequence<std::tuple_size_v<std::remove_reference_t<Tuple>>>())
);

template <class Fn, class Tuple>
struct apply_result_impl {}; // exposition-only

template<class Fn, class Tuple>
    requires requires { typename std::apply_result_t<Fn, Tuple>; }
struct apply_result_impl<Fn, Tuple >
{
    using type = std::apply_result_t<Fn, Tuple>;
};
} // namespace detail

template<class Fn, class Tuple>
struct apply_result : detail::apply_result_impl<Fn, Tuple>{};

참고 사항

std::apply_result(및 해당 별칭 std::apply_result_t)는 std::apply의 반환 타입에 사용돼요. (C++26부터)

Feature-test 매크로 표준 기능
__cpp_lib_reflection 202506L (C++26) : 리플렉션 라이브러리 지원.

예제

#include <type_traits>

struct S
{
    double operator()(char, int&);
    float operator()(int) { return 1.0f; }
};

int main()
{
    std::apply_result_t<S, char, int&> a{3.14};
    static_assert(std::is_same_v<decltype(a), double>);

    std::apply_result_t<S, int> b{2.71f};
    static_assert(std::is_same_v<decltype(b), float>);
}

같이 보기

apply (C++17) 튜플의 인자들로 함수를 호출해요 (함수 템플릿) [편집]
invoke invoke_r (C++17) (C++23) 주어진 인자들로 Callable 객체를 호출하고 반환 타입을 지정할 수 있어요 (C++23부터) (함수 템플릿) [편집]
result_of invoke_result (C++11) (C++20에서 제거) (C++17) 인자 집합으로 호출 가능한 객체를 호출한 결과 타입을 추론해요 (클래스 템플릿) [편집]
declval (C++11) 비평가 맥락에서 사용하기 위해 템플릿 타입 인자의 객체에 대한 참조를 얻어요 (함수 템플릿) [편집]
invocable regular_invocable (C++20) (C++20) 호출 가능 타입이 주어진 인자 타입 집합으로 호출될 수 있음을 지정해요 (개념) [편집]
is_invocable is_invocable_r is_nothrow_invocable is_nothrow_invocable_r (C++17) (C++17) (C++17) (C++17) 타입이 주어진 인자 타입들로 (std::invoke처럼) 호출될 수 있는지 확인해요 (클래스 템플릿) [편집]
is_invocable_type is_invocable_r_type is_nothrow_invocable_type is_nothrow_invocable_r_type (C++26) (C++26) (C++26) (C++26) 리플렉션된 타입이 주어진 인자 타입들로 (std::invoke처럼) 호출될 수 있는지 확인해요 (함수 템플릿) [편집]
is_applicable is_nothrow_applicable (C++26) (C++26) 타입이 주어진 튜플 인자들로 (std::invoke처럼) 호출될 수 있는지 확인해요 (클래스 템플릿) [편집]
apply_result (C++26) 주어진 리플렉션된 튜플 인자들로 호출 가능 객체를 호출한 결과 타입을 추론해요 (함수) [편집]

더 알아보기 (Learn more)

cppreference