std:: disjunction
|
헤더에 정의됨
<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 메타함수
(클래스 템플릿) |
|
(C++17)
|
가변 인자 논리 AND 메타함수
(클래스 템플릿) |