C/CPP: integral_constant

51 篇文章 2 订阅

std::integral_constant

 from std::integral_constant - cppreference.com

C++

Utilities library

Type support

Defined in header <type_traits>

template< class T, T v >
struct integral_constant;

(since C++11)

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.

Helper templates

A helper alias template std::bool_constant is defined for the common case where T is bool.

template <bool B>
using bool_constant = integral_constant<bool, B>;

(since C++17)

Two typedefs for the common case where T is bool are provided:

Defined in header <type_traits>

TypeDefinition
true_typestd::integral_constant<bool, true>
false_typestd::integral_constant<bool, false>

Member types

TypeDefinition
value_typeT
typestd::integral_constant<T,v>

Member constants

NameValue

constexpr T value

[static]

static constant of type T with value v
(public static member constant)

Member functions

operator value_type

returns the wrapped value
(public member function)

operator()

(C++14)

returns the wrapped value
(public member function)

std::integral_constant::operator value_type

constexpr operator value_type() const noexcept;

Conversion function. Returns the wrapped value.

std::integral_constant::operator()

constexpr value_type operator()() const noexcept;

(since C++14)

Returns the wrapped value. This function enables std::integral_constant to serve as a source of compile-time function objects.

Possible implementation

template<class T, T v>
struct integral_constant {
    static constexpr T value = v;
    using value_type = T;
    using type = integral_constant; // using injected-class-name
    constexpr operator value_type() const noexcept { return value; }
    constexpr value_type operator()() const noexcept { return value; } // since c++14
};

Example

#include <type_traits>
 
int main() 
{
    typedef std::integral_constant<int, 2> two_t;
    typedef std::integral_constant<int, 4> four_t;
 
//  static_assert(std::is_same<two_t, four_t>::value,
//                "two_t and four_t are not equal!"); 
//  error: static assertion failed: "two_t and four_t are not equal!"
 
    static_assert(two_t::value*2 == four_t::value,
       "2*2 != 4"
    );
 
    enum class my_e { e1, e2 };
 
    typedef std::integral_constant<my_e, my_e::e1> my_e_e1;
    typedef std::integral_constant<my_e, my_e::e2> my_e_e2;
 
    static_assert(my_e_e1() == my_e::e1);
 
//  static_assert(my_e_e1::value == my_e::e2,
//               "my_e_e1::value != my_e::e2");
//  error: static assertion failed: "my_e_e1::value != my_e::e2"
 
    static_assert(std::is_same<my_e_e2, my_e_e2>::value,
                  "my_e_e2 != my_e_e2");
}

vs. constexpr

from: c++ - When would I use std::integral_constant over constexpr? - Stack Overflow

#include <iostream>
#include <type_traits>

int main(){

    //creating an integral constant with constexpr
    constexpr unsigned int speed_of_light{299792458};

    //creating an integral constant with std::integral_constant
    typedef std::integral_constant<unsigned int, 299792458> speed_of_light_2;

    //using them
    std::cout << speed_of_light/2 << '\n';
    std::cout << speed_of_light_2::value/2 << '\n';

}

What's special about std::integral_constant that I would choose to use it over constexpr?
Their behaviour and use cases look identical to me. I'm trying to think of some kind of template scenario, where constexpr may not suffice.

  • I've never understood the use case of std::integral_constant to be for making integral constants. It's a TMP feature used for various kinds of things, especially tag dispatching (usually based on its specializations std::true_type and std::false_type), something a constant value cannot be used for. Of course for constants use actual constants and not some strange typified constant. 

    – Christian Rau

     Dec 4 '13 at 8:24 
  • There is a lot more on this at Why does Boost MPL have integral constants? 

    – Mankka

Template integral_constant defines a type, keyword constexpr defines a constant. For example std::true_type is std::integral_constant<bool, true>.

One of the usage examples (for integral_constant) itag-dispatching.

template<typename T>
void use_impl(const T&, std::false_type)
{
}

template<typename T>
void use_impl(const T&, std::true_type)
{
}

template<typename T>
void use(const T& v)
{
   use_impl(v, typename std::is_integral<T>::type());
}

Live example

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值