Namespaces
Variants

std:: declval

From cppreference.net
Utilities library
헤더 파일에 정의됨 <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-사용 되면 프로그램은 형식에 맞지 않습니다.

목차

매개변수

(없음)

반환값

평가될 수 없으며 따라서 값을 반환하지 않습니다. 반환 타입은 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)
호출 가능 객체를 인수 집합으로 호출한 결과 타입을 추론함
(클래스 템플릿)