Namespaces
Variants

decltype specifier (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const / volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

엔티티의 선언된 형식 또는 표현식의 형식과 값 범주를 검사합니다.

목차

구문

decltype ( entity ) (1)
decltype ( expression ) (2)

설명

1) 인자가 괄호로 묶이지 않은 id-expression 이거나 괄호로 묶이지 않은 class member access 표현식인 경우, decltype은 이 표현식으로 명명된 entity 의 타입을 산출합니다. 이러한 entity가 존재하지 않거나, 인자가 오버로드된 함수 집합을 명명하는 경우 프로그램은 ill-formed입니다.

인자가 괄호로 묶이지 않은 id-expression 이며 structured binding 을 명명하는 경우, decltype은 referenced type 을 산출합니다(구조적 바인딩 선언의 명세에 설명됨).

(C++17부터)

인자가 괄호로 묶이지 않은 id-expression 이며 constant template parameter 를 명명하는 경우, decltype은 템플릿 매개변수의 타입을 산출합니다(템플릿 매개변수가 placeholder type으로 선언된 경우 필요한 타입 추론을 수행한 후). entity가 템플릿 매개변수 객체(상수 객체)인 경우에도 타입은 non-const입니다.

(C++20부터)
2) 인수가 T 타입의 다른 표현식인 경우, 그리고
a) expression value category xvalue 인 경우, decltype은 T && 를 반환합니다;
b) 표현식 의 값 범주가 lvalue 인 경우, decltype은 T & 를 반환합니다;
c) 표현식 의 값 카테고리가 prvalue 인 경우, decltype은 T 를 산출합니다.

표현식 이 클래스 타입의 prvalue를 반환하는 함수 호출이거나, 이러한 함수 호출을 오른쪽 피연산자로 갖는 쉼표 표현식 인 경우, 해당 prvalue에 대해 임시 객체가 도입되지 않습니다.

(C++17까지)

표현식 이 (괄호로 둘러싸인 것을 포함한) 즉시 호출 이 아닌 prvalue인 경우 (C++20부터) , 해당 prvalue로부터 임시 객체가 구체화 되지 않습니다: 이러한 prvalue는 결과 객체를 갖지 않습니다.

(C++17부터)
임시 객체가 생성되지 않기 때문에, 해당 타입은 완전 할 필요가 없으며 사용 가능한 소멸자 를 가질 필요도 없고, 추상 일 수 있습니다. 이 규칙은 하위 표현식에는 적용되지 않습니다: decltype ( f ( g ( ) ) ) 에서 g ( ) 는 완전한 타입을 가져야 하지만, f ( ) 는 그럴 필요가 없습니다.

객체의 이름이 괄호로 둘러싸인 경우, 이는 일반적인 lvalue 표현식으로 처리되므로, decltype ( x ) decltype ( ( x ) ) 는 종종 다른 타입입니다.

decltype 는 람다 관련 타입이나 템플릿 매개변수에 의존하는 타입과 같이 표준 표기법을 사용하여 선언하기 어렵거나 불가능한 타입을 선언할 때 유용합니다.

참고 사항

기능 테스트 매크로 표준 기능
__cpp_decltype 200707L (C++11) decltype

키워드

decltype

예제

#include <cassert>
#include <iostream>
#include <type_traits>
struct A { double x; };
const A* a;
decltype(a->x) y;       // y의 타입은 double (선언된 타입)
decltype((a->x)) z = y; // z의 타입은 const double& (lvalue 표현식)
template<typename T, typename U>
auto add(T t, U u) -> decltype(t + u) // 반환 타입은 템플릿 매개변수에 의존
                                      // C++14부터 반환 타입 추론 가능
{
    return t + u;
}
const int& getRef(const int* p) { return *p; }
static_assert(std::is_same_v<decltype(getRef), const int&(const int*)>);
auto getRefFwdBad(const int* p) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdBad), int(const int*)>,
    "단순히 auto를 반환하는 것은 완벽한 전달(perfect forwarding)이 아닙니다.");
decltype(auto) getRefFwdGood(const int* p) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdGood), const int&(const int*)>,
    "decltype(auto)를 반환하면 반환 타입을 완벽하게 전달합니다.");
// 대안:
auto getRefFwdGood1(const int* p) -> decltype(getRef(p)) { return getRef(p); }
static_assert(std::is_same_v<decltype(getRefFwdGood1), const int&(const int*)>,
    "decltype(반환 표현식)을 반환해도 반환 타입을 완벽하게 전달합니다.");
int main()
{
    int i = 33;
    decltype(i) j = i * 2;
    static_assert(std::is_same_v<decltype(i), decltype(j)>);
    assert(i == 33 && 66 == j);
    auto f = [i](int av, int bv) -> int { return av * bv + i; };
    auto h = [i](int av, int bv) -> int { return av * bv + i; };
    static_assert(!std::is_same_v<decltype(f), decltype(h)>,
        "람다 함수의 타입은 고유하고 이름이 없습니다");
    decltype(f) g = f;
    std::cout << f(3, 3) << ' ' << g(3, 3) << '\n';
}

출력:

42 42

참고문헌

확장 콘텐츠
  • C++23 표준 (ISO/IEC 14882:2024):
  • 9.2.9.5 Decltype 지정자 [dcl.type.decltype]
  • C++20 표준 (ISO/IEC 14882:2020):
  • 9.2.8.4 Decltype 지정자 [dcl.type.decltype]
  • C++17 표준 (ISO/IEC 14882:2017):
  • TBD Decltype 지정자 [dcl.type.decltype]
  • C++14 표준 (ISO/IEC 14882:2014):
  • TBD Decltype 지정자 [dcl.type.decltype]
  • C++11 표준 (ISO/IEC 14882:2011):
  • TBD Decltype 지정자 [dcl.type.decltype]

참고 항목

auto 지정자 (C++11) 표현식에서 추론된 타입을 지정함
(C++11)
평가되지 않는 컨텍스트에서 사용하기 위해 템플릿 타입 인자의 객체에 대한 참조를 얻음
(함수 템플릿)
(C++11)
두 타입이 동일한지 검사함
(클래스 템플릿)
C 문서 for typeof