Namespaces
Variants

std:: disjunction

From cppreference.net
Metaprogramming library
Type traits
Type categories
(C++11)
(C++11) ( DR* )
Type properties
(C++11)
(C++11)
(C++14)
(C++11) (deprecated in C++26)
(C++11) ( until C++20* )
(C++11) (deprecated in C++20)
(C++11)
Type trait constants
Metafunctions
disjunction
(C++17)
(C++17)
Supported operations
Relationships and property queries
Type modifications
Type transformations
(C++11) (deprecated in C++23)
(C++11) (deprecated in C++23)
(C++11)
(C++11) ( until C++20* ) (C++17)

Compile-time rational arithmetic
Compile-time integer sequences
헤더에 정의됨 <type_traits>
template < class ... B >
struct disjunction ;
(C++17부터)

타입 특성 B... 논리적 선언 을 구성하며, 일련의 특성들에 대해 논리적 OR 연산을 효과적으로 수행합니다.

특수화 std :: disjunction < B1, ..., BN > 는 공개적이고 모호하지 않은 베이스를 가집니다.

  • 만약 sizeof... ( B ) == 0 이면, std:: false_type ; 그렇지 않으면
  • B1, ..., BN 중에서 bool ( Bi :: value ) == true 조건을 만족하는 첫 번째 타입 Bi , 또는 그러한 타입이 없으면 BN

기본 클래스의 멤버 이름 중 disjunction operator= 를 제외한 나머지는 숨겨지지 않으며 disjunction 에서 명확하게 사용 가능합니다.

디스정션(disjunction)은 단락 평가(short-circuiting)를 수행합니다: 만약 Bi 와 같은 템플릿 타입 인자 중 bool ( Bi :: value ) ! = false 인 인자가 존재한다면, disjunction < B1, ..., BN > :: value 의 인스턴스화는 j > i Bj :: value 의 인스턴스화를 요구하지 않습니다.

프로그램이 std::disjunction 이나 std::disjunction_v 에 대한 특수화를 추가하는 경우, 그 동작은 정의되지 않습니다.

목차

템플릿 매개변수

B... - 모든 템플릿 인수 Bi 에 대해 Bi :: value 가 인스턴스화되는 경우, 해당 인수는 기본 클래스로 사용 가능해야 하며 bool 로 변환 가능한 멤버 value 를 정의해야 함

헬퍼 변수 템플릿

template < class ... B >
constexpr bool disjunction_v = disjunction < B... > :: value ;
(C++17부터)

가능한 구현

template<class...>
struct disjunction : std::false_type {};
template<class B1>
struct disjunction<B1> : B1 {};
template<class B1, class... Bn>
struct disjunction<B1, Bn...>
    : std::conditional_t<bool(B1::value), B1, disjunction<Bn...>>  {};

참고 사항

disjunction 의 특수화는 반드시 std:: true_type 또는 std:: false_type 에서 상속받는 것은 아닙니다: 단순히 ::value bool 로 명시적 변환되었을 때 true 가 되는 첫 번째 B 에서 상속받거나, 모두 false 로 변환될 경우 마지막 B 에서 상속받습니다. 예를 들어, std :: disjunction < std:: integral_constant < int , 2 > , std:: integral_constant < int , 4 >> :: value 2 입니다.

단락 평가(short-circuit instantiation)는 disjunction 폴드 표현식(fold expressions) 과 구별하게 합니다: ( ... || Bs :: value ) 과 같은 폴드 표현식은 Bs 에 있는 모든 B 를 인스턴스화하는 반면, std :: disjunction_v < Bs... > 는 값을 결정할 수 있게 되면 인스턴스화를 중단합니다. 이는 이후 타입의 인스턴스화 비용이 높거나 잘못된 타입으로 인스턴스화될 경우 심각한 오류를 발생시킬 수 있는 경우에 특히 유용합니다.

기능 테스트 매크로 표준 기능
__cpp_lib_logical_traits 201510L (C++17) 논리 연산자 타입 특성

예제

#include <cstdint>
#include <string>
#include <type_traits>
// values_equal<a, b, T>::value는 a == b일 때만 true입니다.
template<auto V1, decltype(V1) V2, typename T>
struct values_equal : std::bool_constant<V1 == V2>
{
    using type = T;
};
// default_type<T>::value는 항상 true입니다
template<typename T>
struct default_type : std::true_type
{
    using type = T;
};
// 이제 분기문처럼 분리를 사용할 수 있습니다:
template<int I>
using int_of_size = typename std::disjunction< //
    values_equal<I, 1, std::int8_t>,           //
    values_equal<I, 2, std::int16_t>,          //
    values_equal<I, 4, std::int32_t>,          //
    values_equal<I, 8, std::int64_t>,          //
    default_type<void>                         // 반드시 마지막에 위치해야 합니다!
    >::type;
static_assert(sizeof(int_of_size<1>) == 1);
static_assert(sizeof(int_of_size<2>) == 2);
static_assert(sizeof(int_of_size<4>) == 4);
static_assert(sizeof(int_of_size<8>) == 8);
static_assert(std::is_same_v<int_of_size<13>, void>);
// double에서 Foo를 생성 가능한지 확인하면 하드 에러가 발생합니다
struct Foo
{
    template<class T>
    struct sfinae_unfriendly_check { static_assert(!std::is_same_v
**번역 결과:**
- HTML 태그와 속성은 그대로 유지
- `std::is_same_v` 내의 C++ 관련 용어는 번역하지 않음
- 링크 텍스트가 없으므로 번역할 내용이 없음
**참고:** 제공된 HTML 코드에는 번역이 필요한 실제 텍스트 콘텐츠가 포함되어 있지 않습니다. 링크 텍스트가 존재한다면 해당 부분만 한국어로 번역하겠습니다.<T, double>); };
    template<class T>
    Foo(T, sfinae_unfriendly_check<T> = {});
};
template<class... Ts>
struct first_constructible
{
    template<class T, class...Args>
    struct is_constructible_x : std::is_constructible<T, Args...>
    {
        using type = T;
    };
    struct fallback
    {
        static constexpr bool value = true;
        using type = void; // 찾는 것이 없을 때 반환할 타입
    };
    template<class... Args>
    using with = typename std::disjunction<is_constructible_x<Ts, Args...>...,
                                           fallback>::type;
};
// OK, is_constructible<Foo, double> 인스턴스화되지 않음
static_assert(std::is_same_v
(설명: HTML 태그와 속성은 그대로 유지되었으며, C++ 특정 용어인 `std::is_same_v`는 번역되지 않았습니다. 링크 텍스트 부분만 한국어로 번역할 필요가 있었으나, 주어진 텍스트에 번역 가능한 일반 텍스트가 포함되어 있지 않습니다.)<first_constructible<std::string, int, Foo>::with<double>,
                             int>);
static_assert(std::is_same_v
(설명: 원본 텍스트가 HTML 태그와 C++ 관련 용어만으로 구성되어 있어 번역할 일반 텍스트가 없습니다. HTML 태그와 C++ 표준 라이브러리 요소(std::is_same_v)는 번역 대상에서 제외됩니다.)<first_constructible<std::string, int>::with<>, std::string>);
static_assert(std::is_same_v
(설명: 원본 텍스트가 HTML 태그와 C++ 특정 용어(std::is_same_v)로만 구성되어 있어 번역할 일반 텍스트가 없습니다. 모든 지시사항을 준수하여 원본 형식을 그대로 유지했습니다.)<first_constructible<std::string, int>::with<const char*>,
                             std::string>);
static_assert(std::is_same_v
**번역 결과:**
std::is_same_v
**번역 설명:**
- HTML 태그와 속성은 번역하지 않고 원본 그대로 유지
- ``, `` 태그 내의 텍스트는 C++ 관련 용어이므로 번역하지 않음
- `std::is_same_v`는 C++ 표준 라이브러리 템플릿으로 전문 용어이므로 그대로 보존
- 전체 구조와 포맷팅이 원본과 동일하게 유지됨<first_constructible<std::string, int>::with<void*>, void>);
int main() {}

참고 항목

(C++17)
논리 NOT 메타함수
(클래스 템플릿)
가변 인자 논리 AND 메타함수
(클래스 템플릿)