Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the reason behind having std::integral_constant?

Tags:

c++

std

What's the real use case of this?

std::integral_constant

I can understand this is a wrapper with value 2:

typedef std::integral_constant<int, 2> two_t

But why not just use 2 or define a const int value with 2?

like image 222
WhatABeautifulWorld Avatar asked Mar 10 '18 04:03

WhatABeautifulWorld


People also ask

What is the use of Integral_constant?

std::integral_constant This template is designed to provide compile-time constants as types. It is used by several parts of the standard library as the base class for trait types, especially in their bool variant: see true_type and false_type. Its definition in the Standard Library has the same behavior as: C++11.

What is STD Integral_constant?

std::integral_constant wraps a static constant of specified type. It is the base class for the C++ type traits. The behavior of a program that adds specializations for integral_constant is undefined.

What is integral constant c++?

An integral constant expression is an expression that can be evaluated at compile time, and whose type is integral or an enumeration. The situations that require integral constant expressions include array bounds, enumerator values, case labels, bit-field sizes, static member initializers, and value template arguments.


2 Answers

There are a few cases where std::integral_constant is very useful.

One of them is tag dispatch. For example, std::true_type and std::false_type are simply std::integral_constant<bool, true> and std::integral_constant<bool, false> respectively. Every type trait derives from std::true_type or std::false_type, which enables tag dispatch:

template <typename T>
int foo_impl(T value, std::true_type) {
    // Implementation for arithmetic values
}

template <typename T>
double foo_impl(T value, std::false_type) {
    // Implementation for non-arithmetic values
}

template <typename T>
auto foo(T value) {
    // Calls the correct implementation function, which return different types.
    // foo's return type is `int` if it calls the `std::true_type` overload
    // and `double` if it calls the `std::false_type` overload
    return foo_impl(value, std::is_arithmetic<T>{});
}

Also, template metaprogramming libraries typically only have algorithms on lists of types rather than lists of values. If you wanted to use those algorithms for values instead, you'd have to use something like std::integral_constant

like image 98
Justin Avatar answered Oct 04 '22 03:10

Justin


2 is value, while two_t is a type. They are two different abstractions. Each has its purpose.

  • You can't use 2 where a type is expected.
  • You can't use two_t where an integral value is expected.

More importantly, std::true_type and std::false_type are the most widely used specializations of std::integral_constant. They are extensively used in type_traits.

like image 22
R Sahu Avatar answered Oct 04 '22 04:10

R Sahu