utility_declval
utility_declval (비평가 문맥용 헬퍼 템플릿)
이 페이지는 C++ 표준 라이브러리의 std::declval 함수 템플릿에 대해 설명해요. std::declval은 비평가 문맥(unevaluated context)에서 타입을 표현식으로 변환하는 데 사용돼요. 주로 decltype과 함께 사용해서 생성자 없이도 멤버 함수의 반환 타입을 알아낼 수 있게 해줘요.
출처: cppreference
본문
Defined in header <utility> |
||
|---|---|---|
template < class T > typename std :: add_rvalue_reference < T >:: type declval () noexcept ; |
(since C++11) (until C++14) (unevaluated-only) | |
template < class T > std :: add_rvalue_reference_t < T > declval () noexcept ; |
(since C++14) (unevaluated-only) |
비평가 문맥에 나타나는 표현식을 작성하기 위한 헬퍼 템플릿이에요. 일반적으로 decltype의 피연산자로 사용돼요. 비평가 문맥에서 이 헬퍼 템플릿은 임의의 타입 T(불완전 타입일 수도 있어요)를 그 타입의 표현식으로 변환해요. 그래서 생성자를 거치지 않고도 T의 멤버 함수를 사용할 수 있게 해줘요.
std::declval은 비평가 문맥에서만 사용할 수 있고, 정의가 필요하지 않아요. 이 함수를 포함하는 표현식을 평가하는 것은 오류예요. 공식적으로 이 함수가 odr-use되면 프로그램은 ill-formed예요.
반환값 (Return value)
평가될 수 없으므로 값을 반환하지 않아요. 반환 타입은 T&&이에요 (참조 축약 규칙이 적용돼요). 단, T가 (cv 한정된) void인 경우에는 반환 타입이 T예요.
참고 (Notes)
std::declval은 허용되는 템플릿 매개변수들이 공통 생성자가 없지만, 반환 타입이 필요한 동일한 멤버 함수를 가지고 있는 템플릿에서 흔히 사용돼요.
가능한 구현 (Possible implementation)
template < typename T > typename std :: add_rvalue_reference < T >:: type declval () noexcept { static_assert ( false , "declval not allowed in an evaluated context" ); }
예제 (Example)
#include <iostream>
#include <utility>
struct Default
{
int foo() const { return 1; }
};
struct NonDefault
{
NonDefault() = delete;
int foo() const { return 1; }
};
int main()
{
decltype(Default().foo()) n1 = 1; // type of n1 is int
decltype(std::declval<Default>().foo()) n2 = 1; // same
// decltype(NonDefault().foo()) n3 = n1; // error: no default constructor
decltype(std::declval<NonDefault>().foo()) n3 = n1; // type of n3 is int
std::cout << "n1 = " << n1 << '\n'
<< "n2 = " << n2 << '\n'
<< "n3 = " << n3 << '\n';
}
Output:
n1 = 1
n2 = 1
n3 = 1
같이 보기 (See also)
decltype 지정자 (C++11) |
표현식이나 개체의 타입을 얻어요 [edit] |
|---|---|
result_of invoke_result (C++11) (C++20에서 제거됨) (C++17) |
인자 집합으로 호출 가능한 객체를 호출했을 때의 결과 타입을 추론해요 (클래스 템플릿) [edit] |