C++ 什么';有std::integral_常量的原因是什么?

C++ 什么';有std::integral_常量的原因是什么?,c++,std,C++,Std,这个的真正用例是什么 std::integral_constant 我可以理解这是一个值为2的包装器: typedef std::integral_constant<int, 2> two_t typedef标准::积分常数二 但是为什么不直接使用2或者用2定义常量int值呢?2是值,而two\u t是类型。它们是两种不同的抽象。每个人都有自己的目的 不能在需要类型的地方使用2 不能在需要整数值的地方使用two\t 更重要的是,std::true\u type和std::f

这个的真正用例是什么

std::integral_constant
我可以理解这是一个值为2的包装器:

typedef std::integral_constant<int, 2> two_t
typedef标准::积分常数二

但是为什么不直接使用2或者用2定义常量int值呢?

2
是值,而
two\u t
是类型。它们是两种不同的抽象。每个人都有自己的目的

  • 不能在需要类型的地方使用
    2
  • 不能在需要整数值的地方使用
    two\t

更重要的是,
std::true\u type
std::false\u type
std::integral\u常量
最广泛使用的专门化。它们被广泛用于。

在一些情况下,
std::integral_常量
非常有用

其中之一是标签调度。例如,
std::true_type
std::false_type
分别是
std::integral_常量
std::integral_常量
。每个源于
std::true\u-type
std::false\u-type
,它启用标记分派:

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>{});
}
模板
int foo_impl(T值,std::true_类型){
//算术值的实现
}
模板
双foo_impl(T值,std::false_类型){
//非算术值的实现
}
模板
自动foo(T值){
//调用正确的实现函数,该函数返回不同的类型。
//如果foo调用'std::true_type'重载,则其返回类型为'int'
//如果调用'std::false_type'重载,则为'double'
返回foo_impl(值,std::is_算术{});
}


此外,模板元编程库通常只在类型列表上有算法,而不是在值列表上。如果您想使用这些算法来处理值,则必须使用类似下面的
std::integral_constant

代码片段是我使用std::integral_constant创建api的一种方法,该api采用通用值,但它也会在编译时检查您提供的值是否有效

#include<iostream>

struct Value {};
struct Color {};
struct Size {};
struct Point {};

enum class Property {
    Color,
    StrokeColor,
    Opacity,
    Size,
    Position,
};

class Dom {
public:
    // give a single api to setValue
    template<Property prop, typename AnyValue>
    void setValue(const std::string &obj, AnyValue value){
        setValue(std::integral_constant<Property, prop>{}, obj, value);
    }
private:
    // specialization for each property and value type pair.
    void setValue(std::integral_constant<Property, Property::Color> type,
                  const std::string &obj,
                  Color col) {std::cout<<" update color property\n";}
    void setValue(std::integral_constant<Property, Property::StrokeColor> type,
                  const std::string &obj,
                  Color col){std::cout<<" update stroke color property\n";}
    void setValue(std::integral_constant<Property, Property::Opacity> type,
                  const std::string &obj,
                  Value opacity){std::cout<<" update opacity property\n";}
};

int main()
{
    Dom domObj;
    // try to update the color property of rect1 object inside layer1
    domObj.setValue<Property::Color>("layer1.rect1", Color());

    // compile time error expects Color value but given Size value
    //domObj.setValue<Property::Color>("layer1.rect1", Size());
    return 0;
}
#包括
结构值{};
结构颜色{};
结构大小{};
结构点{};
枚举类属性{
颜色
StrokeColor,
不透明度
大小,
立场,,
};
类Dom{
公众:
//为setValue指定一个api
模板
void setValue(const std::string&obj,AnyValue){
setValue(std::整型_常数{},obj,值);
}
私人:
//每个属性和值类型对的专门化。
无效设置值(标准::整型常量类型,
常量标准::字符串和对象,

颜色(col){std::coutIs除了在编译时生成代码的性能增益外,它还相当于添加一个if-else检查?@WhatABeautifulWorld No。您甚至可以在不同的实现中返回不同的类型。这不会只使用
if
进行编译。然而,在C++17中,我们得到
if-constexpr
,而ch确实适用于此用例。如果您使用bool和in代替std::is_算术{}而不是std::true_类型,会怎么样你输入了std::is_算术::value?@Zebrafish,那么不管特征是否为真,你总是会得到一个
bool
,这意味着你只能有一个重载。这不允许不同的返回类型或实现,它们只能在真与假的情况下编译。假设我们可以有非-t类型模板参数,在什么情况下,我们可以使用类型而不是整数值?如果我们的traits类的成员是常量整数值表达式,而不是
true\u类型
false\u类型
,那会排除什么?@Maxpm,我对你的问题有点困惑。你是否可以使用实例化模板的类型或值取决于模板的定义方式。关于第二个问题,我不遵循您的思路。这取决于模板的定义方式,是的,但出于元编程目的,我们可以根据需要定义模板。当我们有语言中已经有了非常好的基于价值的方式?我的第二个问题是:正如你所说,
true\u-type
false\u-type
在类型特征中被广泛使用-但是这是一个怎样的改进?@Maxpm,感谢你澄清了你的问题。这些问题的答案不仅很长,而且也很有哲理性不是回答它们的正确位置。好的。“这不是回答它们的正确位置”意味着这个评论线程,或者这个问题,或者通常的堆栈溢出?