【问题标题】:Compile-time optimization for `std::isfinite()` applied to the integral types应用于整数类型的 `std::isfinite()` 的编译时优化
【发布时间】:2019-08-17 07:10:27
【问题描述】:

我有一个设计选择。我有一个模板化类myClass<T>,它有一个T 类型的成员data_。目前,打算支持int,几种复杂类型,和double;从而产生了三类模板:浮点型、整数型和复数型。

函数checkValidity(),检查类myClass的对象的有效性,现在仅限于使用std::isfinite()检查data_的有限性。

目前实现了这个功能,如下:

template<class T>
bool myClass<T>::checkValidity() const noexcept
{
    if constexpr(std::is_floating_point_v<T> || std::is_integral_v<T>)
    {
        return std::isfinite(this->data_);
    }
    else if constexpr(is_complex<T>{})
    {
        return (std::isfinite(this->data_.real()) && std::isfinite(this->data_.imag()))
    }
    else static_assert(assert_false<T>::value , "wrong type");
}

其中is_complex&lt;T&gt;{}assert_false&lt;T&gt; 是简单的自定义书面特征,它们确定类型是否是受支持的复杂类型之一,并简单地防止使用不支持的T 类型进行编译,该类型已被错误地用于实例化,分别。

现在,我想知道,由于integral types are always finite,将条件从第一个constexpr if 分支移出是否有意义,如下所示:

if constexpr(std::is_integral_v<T>)
{
    return true;
}

?

因为据我了解std::isfinite(value),其中value 是整数类型将始终返回true

差不多可以归结为这个问题:

  • 当已知整数类型(如我的示例)时,明确检查整数类型的有限性是否有意义?
  • 我是否希望编译器针对 T = int 的情况优化我未修改的版本?

场地:

【问题讨论】:

  • 关于编译器是否足够聪明以优化 is_finite 调用,答案似乎是肯定的:godbolt.org/z/awCMhc
  • 您的整个问题都有错字。是std::isfinite 不是std::is_finite ;) 除此之外,我同意@Chuu Plus...std::isfinite 不是constexpr。如果这对你很重要......
  • @jan.sende 非常感谢!固定的。我的注意力转移到使其他所有语法都正确。 std::isfinite 不是 constexpr 的事实无关紧要。
  • @Chuu 好观察!

标签: c++ c++17 cmath


【解决方案1】:

随着时间的推移,您将对编译器将优化成常量的内容产生直觉。如果您不确定,并且为了建立您的直觉,您应该使用 Compiler Explorer 等工具来查看编译器实际生成的内容。

Here 是您在编译器资源管理器中提出的实现的非常粗略的模型。如果您直观地期望 std::isfinite 将计算任何整数数据类型的常量表达式,那么结果并不令人惊讶。同样遵循这种直觉,double 案例简化为内联的 std::isfinite 调用,您可以在编译器资源管理器中通过查看生成的调用来验证一个简单的方法,该方法只调用 std::isfinite 以获得双精度。

对于实际的复杂类,您可以使用该工具更深入地模拟您的 Complex 类,并查看编译器如何处理它。

【讨论】:

    猜你喜欢
    • 2020-12-03
    • 1970-01-01
    • 2011-03-19
    • 1970-01-01
    • 1970-01-01
    • 2012-03-21
    • 1970-01-01
    • 2013-01-12
    • 2022-06-15
    相关资源
    最近更新 更多