Namespaces
Variants

std::declval

cppreference.net에서
 
 
유틸리티 라이브러리
일반 유틸리티
관계 연산자 (C++20에서 폐지됨)
정수 비교 함수
(C++20)(C++20)(C++20)    
(C++20)
교체 및 타입 연산
(C++14)
(C++11)
(C++11)
(C++11)
(C++17)
공통 어휘 타입
(C++11)
(C++17)
(C++17)
(C++17)
(C++11)
(C++17)
(C++23)



 
헤더 <utility>
template< class T >
typename std::add_rvalue_reference<T>::type declval() noexcept;
에 정의됨
(C++11부터)
(C++14까지)
template< class T >
std::add_rvalue_reference_t<T> declval() noexcept;
(비평가 전용)
(C++14부터)

(비평가 전용)비평가 문맥에 나타나는 표현식을 작성하기 위한 도우미 템플릿이며, 일반적으로 decltype의 피연산자로 사용됩니다. 비평가 문맥에서 이 도우미 템플릿은 임의의 타입 T (불완전 타입일 수 있음)을 해당 타입의 표현식으로 변환하여, 생성자를 거치지 않고 T의 멤버 함수를 사용할 수 있게 합니다.

std::declval은 오직 비평가 문맥에서만 사용 가능하며, 정의될 필요가 없습니다. 이 함수를 포함하는 표현식을 평가하는 것은 오류입니다. 공식적으로, 이 함수가 odr-사용되는 경우 프로그램은 잘못된 형식(ill-formed)입니다.

매개변수

(없음)

반환값

평가될 수 없으며 따라서 값을 반환하지 않습니다. 반환 타입은 T&& (참조 축소 규칙이 적용됨)이며, 단 T 가 (cv 한정자가 있을 수 있는) void 인 경우에는 반환 타입이 T 입니다.

참고 사항

std::declval 는 허용 가능한 템플릿 매개변수들이 공통된 생성자를 가지지 않을 수 있지만, 동일한 멤버 함수를 가지며 그 반환 타입이 필요한 템플릿에서 일반적으로 사용됩니다.

가능한 구현

template<typename T>
typename std::add_rvalue_reference<T>::type declval() noexcept
{
    static_assert(false, "declval not allowed in an evaluated context");
}

예제

#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;     // n1의 타입은 int
    decltype(std::declval<Default>().foo()) n2 = 1;     // 동일
//  decltype(NonDefault().foo())               n3 = n1; // 오류: 기본 생성자가 없음
    decltype(std::declval<NonDefault>().foo()) n3 = n1; // n3의 타입은 int
    std::cout << "n1 = " << n1 << '\n'
              << "n2 = " << n2 << '\n'
              << "n3 = " << n3 << '\n';
}

출력:

n1 = 1
n2 = 1
n3 = 1

참고 항목

decltype 지정자 (C++11) 표현식 또는 엔티티의 타입을 얻음
(C++11) (C++20에서 제거됨) (C++17)
호출 가능 객체를 인수 집합으로 호출한 결과 타입을 추론함
(클래스 템플릿)