Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 三维矢量的高效除法算子_C++_Operator Overloading_Division_Sfinae_Micro Optimization - Fatal编程技术网

C++ 三维矢量的高效除法算子

C++ 三维矢量的高效除法算子,c++,operator-overloading,division,sfinae,micro-optimization,C++,Operator Overloading,Division,Sfinae,Micro Optimization,我有一个简单的3D向量类模板: template <typename T> struct Vec3 { T x, y, z; // vector components ... } 关于这段代码的几个问题: 是否有其他非SFINAE方法将此成员函数限制为浮动 点类型?(我正在使用C++17) 现代编译器是否足够聪明,可以先计算除法,然后再计算除法 然后执行三次乘法?这是浪费时间吗 我自己也能做到吗 是否值得为常量1.0使用变量模板?编译器是否足够聪明,可以在编译时

我有一个简单的3D向量类模板:

template <typename T>
struct Vec3
{
    T x, y, z;  // vector components
    ...
}
关于这段代码的几个问题:

  • 是否有其他非SFINAE方法将此成员函数限制为浮动 点类型?(我正在使用C++17)
  • 现代编译器是否足够聪明,可以先计算除法,然后再计算除法 然后执行三次乘法?这是浪费时间吗 我自己也能做到吗
  • 是否值得为常量
    1.0
    使用变量模板?编译器是否足够聪明,可以在编译时执行静态_转换

    模板
    constexpr t1=T(1.0);
    
编辑:gcc不介意,但是clang不会编译上面的代码。这是因为我对SFINAE的使用不正确。正确的实施将是

template <typename U = T,
          typename = std::enable_if_t<std::is_floating_point_v<U>>>
Vec3 operator/(T a) const
{
    ...
}
模板
Vec3算子/(ta)常数
{
...
}
更多详细信息可在此处找到:

  • 是否有其他非SFINAE方法将此成员函数限制为浮点类型?(我正在使用C++17)
  • 类的全部或部分专门化(对于部分专门化,需要更改以使类SFINAE友好)
  • 重载为自由函数(如
    std::is_floating_point_v
    仅对少数类型有效(
    float
    double
    long double
    (+cv\u variant)))

    • 现代编译器是否足够聪明,可以先计算除法,然后执行三次乘法?自己这样做是浪费时间和表达能力吗
    对于浮点运算,结果可能不同,所以编译器不会这样做(除非它能确保结果相同)

    • 是否值得为常量1.0使用变量模板?编译器是否足够聪明,可以在编译时执行静态_转换
    我相信编译器会用
    1.f

    替换代码
    static\u cast(1.0)
    “足够聪明”是的,但前提是使用
    -ffast math
    ,除非已知除数有一个倒数,可以精确表示为
    T
    。e、 g.对于编译时常数幂2,如
    2.0
    0.5
    ,是的,因为二进制浮点可以表示这样的分数。ISO C++ + IEEE-75规则不允许引入不精确的倒数。
    template<typename T>
    constexpr T one = T(1.0);
    
    template <typename U = T,
              typename = std::enable_if_t<std::is_floating_point_v<U>>>
    Vec3 operator/(T a) const
    {
        ...
    }
    
    Vec3<float> operator / (const Vec3<float>& vec, float value) {/*..*/}
    Vec3<double> operator / (const Vec3<float>& vec, float value) {/*..*/}
    Vec3<long double> operator / (const Vec3<float>& vec, float value) {/*..*/}
    
    Vec3 operator/(T a) const requires(std::is_floating_point_v<T>) {/*..*/}