【问题标题】:literals in template function for floating point types浮点类型的模板函数中的文字
【发布时间】:2014-12-12 07:44:34
【问题描述】:

这个问题之前已经出现过,特别是在这里Should we generally use float literals for floats instead of the simpler double literals?,但我想知道现在我们在 C++14 领域是否有更好的建议解决方案,并且存在诸如用户定义的文字和大括号初始化之类的东西。

问题可以表述为如何在浮点类型的模板函数中写一个浮点字面量

template <typename T> T foo( T x )
{
    static_assert( std::is_floating_point<T>::value, "" );

    T y = x * 101.0;

    return( y );
}

所以问题归结为我们如何写“101.0”,因为它是一个双倍,所以如果我调用 foo 会发生什么

float a = 42.0f;
float b = foo( a );

如果我在 foo 中写“101.0f”,如果我用双精度调用 foo 会发生什么,请注意 101.0 和 101.0f 不一定相同。

另外我如何保证不会产生额外的代码来转换值?

其他建议包括编写诸如“static_cast(101.0)”、“T(101.0)”之类的东西或其他可怕的东西!

【问题讨论】:

  • [conv.fpprom]: "float 类型的纯右值可以转换为 double 类型的纯右值。该值不变。这种转换称为 浮点提升。”
  • static_cast&lt;T&gt;(100.0) 怎么样?
  • Littering static_cast 虽然当函数具有合理数量的文字时代​​码变得非常丑陋。我希望有更简洁的东西!
  • 请注意,在包含多个变量和文字的较长表达式中,如果 T 为双精度,我不确定所有浮点文字在编译时都会转换为双精度(我有一个测试用例表明情况并非如此至少在 VS 2013 上)

标签: c++ c++11 c++14


【解决方案1】:

特定于 C++14 的选项是使用 variable template

namespace detail
{
    template<typename F>
    F multiplier = F(101.0);
}

template <typename T> T foo( T x )
{
    static_assert( std::is_floating_point<T>::value, "" );

    T y = x * detail::multiplier<T>;

    static_assert(std::is_same<decltype(detail::multiplier<T>), T>{}, "");

    return( y );
}

Live demo

【讨论】:

    【解决方案2】:
    template <typename T> T foo( T x ){
      static_assert( std::is_floating_point<T>::value, "" );
    
      T y = x * foo_constants<T>::one_o_one;
    
      return( y );
    }
    

    然后只需在 foo_constants 结构中定义和专门化您的常量。

    您可能甚至不再需要静态断言了。您甚至可以将您的函数扩展到其他代数(向量积、矩阵、四元数等)。

    但是,它不符合您的简洁性要求。

    【讨论】:

    • 我确实使用过这种方法一段时间。对每个可能的字面值进行模板特化是一件痛苦的事,而且似乎陷入了围绕桶的可怕工作。目前我的真实代码库有大约 100 个不同的文字值!我同意这种技术对于像 pi 这样的常量是合理的,我仍然在使用它。
    • 您不一定需要将它们放在单独的结构中。您所需要的只是模板能够找到它们。然后根据你想要的捆绑方式调制。 Pi 通常是提升失败的常量(我猜任何不合理的值都需要以这种方式处理,或者使用模板化的上下文)。
    猜你喜欢
    • 1970-01-01
    • 2020-12-20
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 2012-06-20
    • 2018-10-23
    • 2014-03-25
    • 1970-01-01
    相关资源
    最近更新 更多