std::invocable / regular_invocable
std::invocable / regular_invocable (호출 가능 개념)
호출 가능 타입 F를 함수 템플릿 std::invoke로 인자 집합 Args...와 함께 호출할 수 있는지를 명세하는 개념(concept)이에요. regular_invocable은 여기에 동등성 보존과 비수정 조건을 더해요. C++20부터 있어요.
출처: cppreference
본문
<concepts> 헤더에 정의돼 있어요.
template< class F, class... Args >
concept invocable =
requires(F&& f, Args&&... args) {
std::invoke(std::forward<F>(f), std::forward<Args>(args)...);
/* 동등성 보존이 요구되지는 않음 */
};
template< class F, class... Args >
concept regular_invocable = std::invocable<F, Args...>;
invocable 개념은 호출 가능 타입 F가 함수 템플릿 std::invoke를 사용해 인자 집합 Args...와 함께 호출될 수 있음을 명세해요.
regular_invocable 개념은 invocable에 더해 invoke 표현식이 동등성 보존이어야 하고 함수 객체나 인자를 수정하지 않아야 한다는 조건을 추가해요.
동등성 보존
표준 라이브러리 개념의 requires 표현식에서 선언된 표현식들은 (달리 명시되지 않는 한) 동등성 보존이어야 해요. 다만 invocable의 경우 위 코드 주석처럼 동등성 보존이 요구되지는 않아요 — 그래서 regular_invocable이 별도로 존재해요.
참고
invocable과 regular_invocable의 구분은 순전히 의미적(semantic)이에요.
난수 생성기는 invocable을 만족할 수 있지만 regular_invocable은 만족할 수 없어요(웃긴 경우는 제외). 호출할 때마다 다른 값을 내므로 동등성 보존이 아니기 때문이에요.
참고 문헌
- C++23 표준 (ISO/IEC 14882:2024): 18.7.2 Concept invocable [concept.invocable], 18.7.3 Concept regular_invocable [concept.regularinvocable]
- C++20 표준 (ISO/IEC 14882:2020): 18.7.2 Concept invocable [concept.invocable], 18.7.3 Concept regular_invocable [concept.regularinvocable]