【问题标题】:When would I use std::integral_constant over constexpr?我什么时候会在 constexpr 上使用 std::integral_constant?
【发布时间】:2013-12-20 12:22:42
【问题描述】:
#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';

}

std::integral_constant 有什么特别之处,我会选择使用它而不是 constexpr
他们的行为和用例看起来和我一模一样。我正在尝试考虑某种模板场景,其中 constexpr 可能不够。

【问题讨论】:

  • 我从来不理解std::integral_constant 的用例是用于制作整数常量。这是用于各种事物的 TMP 功能,尤其是标签调度(通常基于其专业化 std::true_typestd::false_type),不能使用常量值。当然对于常量使用实际常量而不是一些奇怪的典型常量。
  • Why does Boost MPL have integral constants? 有更多关于此的信息

标签: c++ templates c++11 constants constexpr


【解决方案1】:

模板integral_constant 定义一个类型,关键字constexpr 定义一个常量。 例如std::true_typestd::integral_constant&lt;bool, true&gt;

其中一个用法示例是tag-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

【讨论】:

  • 但是如果 std::true_type 被定义为 "constexpr bool true_type = true; 我看不出这会如何改变它的行为。也许 constexpr 创建了一个实际的实例,但整数常量只定义了一个类型...不,我不这么认为。我不确定。
  • @TrevorHickey 它不会有其他类型,在 constexpr 的情况下它只会有 bool 类型。
  • 哦,在编译时根据值做出决定。我想知道是否可以使用三元运算符和 constexpr 来匹配该行为。不管怎样,我现在看到了它的价值。
  • 一般情况下不会。编译器(至少是 gcc)将尝试实例化所有“可达”块中的对象,即使优化器稍后会因 constexpr 条件而剔除这些块。这不会发生在模板化表达式中,因为 SFINAE 推断会提前发生。
【解决方案2】:

可以和三元运算符一起使用 例如

void gotoN_impl(std::integral_constant<int,0>::type)
{
    std::cout << "GoTo 0" << '\n';
}

void gotoN_impl(std::integral_constant<int,1>::type)
{
    std::cout << "GoTo 1" << '\n';
}

void gotoN_impl(std::integral_constant<int,2>::type)
{
    std::cout << "GoTo 2" << '\n';
}

void gotoN_impl(std::integral_constant<int,3>::type)
{
    std::cout << "GoTo 3" << '\n';
} 

template<int N>
void gotoN()
{
    gotoN_impl(typename std::integral_constant<int, N>::type());
}


int main()
{
    gotoN<0>();
    gotoN<1>();
    gotoN<2>();
    gotoN<3>();

    constexpr auto x = 99;

    gotoN<x<4?x:3>(); // with a ternary operator
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-08
    • 1970-01-01
    • 1970-01-01
    • 2017-07-24
    • 1970-01-01
    • 2020-03-24
    • 2020-10-01
    相关资源
    最近更新 更多