types_is_constant_evaluated

types_is_constant_evaluated (상수 평가 여부 판별)

std::is_constant_evaluated는 현재 함수 호출이 상수 평가(constant-evaluated) 컨텍스트에서 발생하는지 여부를 컴파일 타임에 판별하는 함수예요. C++20부터 <type_traits> 헤더에서 제공되며, constexpr ifstatic_assert와 함께 사용해 컴파일 타임과 런타임 경로를 분리할 수 있어요. 이 함수는 컴파일러 최적화와 코드 생성에 유용한 힌트를 제공해요.

출처: cppreference

본문

개요

<type_traits> 헤더에 정의됨
constexpr bool is_constant_evaluated () noexcept ; (C++20부터)

함수 호출이 상수 평가 컨텍스트 안에서 발생하는지 감지해요. 호출의 평가가 명백히 상수 평가되는(manifestly constant-evaluated) 표현식 또는 변환의 평가 안에서 발생하면 true를 반환하고, 그렇지 않으면 false를 반환해요.

시험적 상수 평가

다음 변수들의 초기화가 명백히 상수 평가되는지 결정하기 위해, 컴파일러는 먼저 시험적 상수 평가(trial constant evaluation)를 수행할 수 있어요:

  • 참조 타입 또는 const 한정 정수·열거형 타입을 가진 변수
  • static 및 스레드 지역 변수

이 경우 결과에 의존하는 것은 권장되지 않아요.

int y = 0;
const int a = std::is_constant_evaluated() ? y : 1;
// Trial constant evaluation fails. The constant evaluation is discarded.
// Variable a is dynamically initialized with 1

const int b = std::is_constant_evaluated() ? 2 : y;
// Constant evaluation with std::is_constant_evaluated() == true succeeds.
// Variable b is statically initialized with 2

매개변수

(없음)

반환값

호출의 평가가 명백히 상수 평가되는 표현식 또는 변환의 평가 안에서 발생하면 true를 반환하고, 그렇지 않으면 false를 반환해요.

가능한 구현

// This implementation requires C++23 if consteval. constexpr bool is_constant_evaluated () noexcept { if consteval { return true ; } else { return false ; } }

참고 사항

static_assert 선언이나 constexpr if 문의 조건으로 직접 사용될 때, std::is_constant_evaluated()는 항상 true를 반환해요.

C++20에는 if consteval이 없기 때문에, std::is_constant_evaluated는 일반적으로 컴파일러 확장을 사용해 구현돼요.

기능 테스트 매크로 표준 기능
__cpp_lib_is_constant_evaluated 201811L (C++20) std::is_constant_evaluated

예제

#include <cmath>
#include <iostream>
#include <type_traits>

constexpr double power(double b, int x)
{
    if (std::is_constant_evaluated() && !(b == 0.0 && x < 0))
    {
        // A constant-evaluation context: Use a constexpr-friendly algorithm.
        if (x == 0)
            return 1.0;
        double r {1.0};
        double p {x > 0 ? b : 1.0 / b};
        for (auto u = unsigned(x > 0 ? x : -x); u != 0; u /= 2)
        {
            if (u & 1)
                r *= p;
            p *= p;
        }
        return r;
    }
    else
    {
        // Let the code generator figure it out.
        return std::pow(b, double(x));
    }
}

int main()
{
    // A constant-expression context
    constexpr double kilo = power(10.0, 3);
    int n = 3;
    // Not a constant expression, because n cannot be converted to an rvalue
    // in a constant-expression context
    // Equivalent to std::pow(10.0, double(n))
    double mucho = power(10.0, n);

    std::cout << kilo << " " << mucho << "\n"; // (3)
}

출력:

1000 1000

같이 보기

constexpr 지정자 (C++11) 변수나 함수의 값이 컴파일 타임에 계산될 수 있음을 지정해요 [편집]
consteval 지정자 (C++20) 함수가 즉시 함수(immediate function)임을 지정해요. 즉, 함수에 대한 모든 호출이 상수 평가 안에 있어야 해요 [편집]
constinit 지정자 (C++20) 변수가 정적 초기화, 즉 0 초기화 및 상수 초기화를 가짐을 단언해요 [편집]

더 알아보기 (Learn more)

cppreference