std:: common_reference
|
헤더에 정의됨
<type_traits>
|
||
|
template
<
class
...
T
>
struct common_reference ; |
(C++20부터) | |
T...
타입들의 공통 참조 타입을 결정합니다. 즉,
T...
에 있는 모든 타입들이 변환되거나 바인딩될 수 있는 타입을 의미합니다. 이러한 타입이 존재하는 경우(아래 규칙에 따라 결정됨), 멤버
type
은 해당 타입을 나타냅니다. 그렇지 않으면 멤버
type
이 존재하지 않습니다.
T...
에 포함된 어떤 타입이 (가능하게는 cv-qualified)
void
를 제외한 불완전한 타입인 경우의 동작은 정의되지 않습니다.
참조 타입이 주어졌을 때,
common_reference
는 제공된 참조 타입들이 모두 바인딩될 수 있는 참조 타입을 찾으려 시도하지만, 그러한 참조 타입을 찾을 수 없는 경우 비-참조 타입을 반환할 수 있습니다.
-
만약
sizeof...
(
T
)
이 0이면,
type멤버가 존재하지 않습니다. -
만약
sizeof...
(
T
)
이 1이면 (즉,
T...이 단 하나의 타입T0만을 포함하는 경우),type멤버는 T0 와 동일한 타입을 나타냅니다. -
만약
sizeof...
(
T
)
이 2이면 (즉,
T...이 두 타입T1과T2를 포함하는 경우):-
타입
S를T1과T2의 단순 공통 참조 타입 (아래에 정의됨)이라고 합시다. 아래 조건들이 모두 만족될 때 멤버 타입type은S를 나타냅니다:-
T1과T2가 모두 참조 타입인 경우 -
S가 잘 정의된 경우
-
-
타입
|
(C++23부터) |
-
-
그렇지 않고,
std
::
basic_common_reference
<
std::
remove_cvref_t
<
T1
>
,
std::
remove_cvref_t
<
T2
>
, T1Q, T2Q
>
::
type
가 존재하고, 여기서
TiQ는 TiQ < U > 가U에Ti의 cv- 및 참조 한정자를 추가한 형태인 단항 별칭 템플릿일 경우, 멤버 타입type은 해당 타입을 나타냅니다;
-
그렇지 않고,
std
::
basic_common_reference
<
std::
remove_cvref_t
<
T1
>
,
std::
remove_cvref_t
<
T2
>
, T1Q, T2Q
>
::
type
가 존재하고, 여기서
-
-
그렇지 않고,
decltype
(
false
?
val
<
T1
>
(
)
:
val
<
T2
>
(
)
)
가 유효한 타입인 경우(여기서
val은 함수 템플릿 template < class T > T val ( ) ; 임), 멤버 타입type은 해당 타입을 나타냅니다; -
그렇지 않고,
std::
common_type_t
<
T1, T2
>
가 유효한 타입인 경우, 멤버 타입
type은 해당 타입을 나타냅니다; -
그렇지 않으면, 멤버
type이 존재하지 않습니다.
-
그렇지 않고,
decltype
(
false
?
val
<
T1
>
(
)
:
val
<
T2
>
(
)
)
가 유효한 타입인 경우(여기서
-
만약
sizeof...
(
T
)
이 2보다 큰 경우(즉,
T...이T1, T2, R...타입들로 구성된 경우), std :: common_reference_t < T1, T2 > 이 존재하면, 멤버type은 std :: common_reference_t < std :: common_reference_t < T1, T2 > , R... > 타입이 존재할 경우 이를 나타냅니다. 다른 모든 경우에는 멤버type이 존재하지 않습니다.
두 참조 타입
T1
과
T2
의
단순 공통 참조 타입
은 다음과 같이 정의됩니다:
-
만약
T1이cv1 X&이고T2가cv2 Y&인 경우(즉, 둘 다 lvalue 참조 타입인 경우): 이들의 단순 공통 참조 타입은 decltype ( false ? std:: declval < cv12 X & > ( ) : std:: declval < cv12 Y & > ( ) ) 이며, 여기서 cv12 는 cv1 과 cv2 의 합집합입니다. 단, 해당 타입이 존재하고 참조 타입인 경우에 한합니다; -
만약
T1과T2가 모두 rvalue 참조 타입인 경우:T1&와T2&의 단순 공통 참조 타입(이전 항목에 따라 결정됨)이 존재하면,C를 해당 타입에 대응하는 rvalue 참조 타입으로 표기합니다. 만약 std:: is_convertible_v < T1, C > 와 std:: is_convertible_v < T2, C > 가 모두 true 이면,T1과T2의 단순 공통 참조 타입은C입니다; -
그렇지 않은 경우, 두 타입 중 하나는 lvalue 참조 타입
A&이고 다른 하나는 rvalue 참조 타입B&&이어야 합니다(A와B는 cv-qualified일 수 있음).D를 A & 와 B const & 의 단순 공통 참조 타입(존재하는 경우)으로 표기합니다. 만약 D 가 존재하고 std:: is_convertible_v < B && , D > 가 true 이면, 단순 공통 참조 타입은D입니다; - 그렇지 않으면, 단순 공통 참조 타입이 존재하지 않습니다.
위에서 사용된 false ? X : Y 와 같은 표현식의 타입 정의에 대해서는 조건 연산자 를 참조하십시오.
목차 |
멤버 타입
| 이름 | 정의 |
type
|
모든
T...
에 대한 공통 참조 타입
|
헬퍼 타입
|
template
<
class
...
T
>
using common_reference_t = std :: common_reference < T... > :: type ; |
||
|
template
<
class
T,
class
U,
template
<
class
>
class
TQual,
template
<
class
>
class
UQual
>
struct basic_common_reference { } ; |
||
클래스 템플릿
basic_common_reference
는 사용자 정의 타입(일반적으로 프록시 참조)에 대한
common_reference
의 결과에 영향을 줄 수 있는 커스터마이제이션 포인트입니다. 기본 템플릿은 비어 있습니다.
특수화
프로그램은 첫 번째 두 매개변수
T
와
U
에 대해
std
::
basic_common_reference
<
T, U, TQual, UQual
>
를 특수화할 수 있습니다. 단,
std::
is_same_v
<
T,
std::
decay_t
<
T
>>
와
std::
is_same_v
<
U,
std::
decay_t
<
U
>>
가 모두
true
이고 둘 중 적어도 하나가 프로그램 정의 타입에 의존하는 경우에 한합니다.
만약 그러한 특수화가
type
이라는 멤버를 가지고 있다면, 이는
TQual
<
T
>
와
UQual
<
U
>
모두 변환 가능한 타입을 지칭하는 공개적이고 모호하지 않은 멤버여야 합니다. 추가적으로,
std
::
basic_common_reference
<
T, U, TQual, UQual
>
::
type
와
std
::
basic_common_reference
<
U, T, UQual, TQual
>
::
type
는 동일한 타입을 지칭해야 합니다.
프로그램은 세 번째 또는 네 번째 매개변수에 대해
basic_common_reference
를 특수화해서는 안 되며,
common_reference
자체를 특수화해서도 안 됩니다. 이러한 규칙을 위반하여 특수화를 추가하는 프로그램은 정의되지 않은 동작을 가집니다.
표준 라이브러리는 다음과 같은
basic_common_reference
특수화를 제공합니다:
두 개의
pair
의 공통 참조 타입을 결정함
(클래스 템플릿 특수화) |
|
tuple
과
tuple-like
타입의 공통 참조 타입을 결정함
(클래스 템플릿 특수화) |
|
reference_wrapper
와
reference_wrapper
가 아닌 타입의 공통 참조 타입을 결정함
(클래스 템플릿 특수화) |
참고 사항
| 기능 테스트 매크로 | 값 | 표준 | 기능 |
|---|---|---|---|
__cpp_lib_common_reference
|
202302L
|
(C++23) | std::common_reference_t 의 std::reference_wrapper 를 참조 타입으로 만들기 |
예제
#include <concepts> #include <type_traits> static_assert( std::same_as< int&, std::common_reference_t< std::add_lvalue_reference_t<int>, std::add_lvalue_reference_t<int>&, std::add_lvalue_reference_t<int>&&, std::add_lvalue_reference_t<int>const, std::add_lvalue_reference_t<int>const& > > ); int main() {}
참고 항목
|
(C++11)
|
여러 타입들의 공통 타입을 결정합니다
(클래스 템플릿) |
|
(C++20)
|
두 타입이 공통 참조 타입을 가짐을 명시합니다
(컨셉트) |