【问题标题】:Template operator() specialization for a special type?特殊类型的模板 operator() 特化?
【发布时间】:2021-12-14 19:10:18
【问题描述】:

我有一个基于模板的 Vector 类。 我有一个基于Scott Meyers Dimensional Analysis in C++ 的单位转换模板。我不会列出它,因为它很复杂,除非没有这些细节就无法解决问题。当我需要将数据传递给外部函数时,我正在使用强制转换运算符。

template<typename T>
struct XYZVector 
{
  operator Point3D() { return Point3D(x, y, z); }
}

如果我使用 T 作为双精度,它工作正常。但是当我这样做时,我需要专业化。

Point3D vecOut = XYZVector<Unit::usFoot>(x,y,z);

会失败,因为在转换 Unit 对象时需要使用 as() 方法。

operator Point3D() { return Point3D( x.as<T>(), y.as<T>(), z.as<T>() ); }

所以我需要以某种方式说如果 T 是一个 Unit 使用这一行,否则使用下一行。

template<typename T>
struct XYZVector
{
  //if typename T is a Unit type use this
  operator Point3D() { return Point3D( x.as<T>(), y.as<T>(), z.as<T>() ) }
  //otherwise use this
  operator Point3D() { return Point3D(x, y, z); }
}

这可能吗?

【问题讨论】:

    标签: c++ templates visual-c++ c++17 c++14


    【解决方案1】:

    if constexpr 来救援。

    operator Point3D() { 
    
         if constexpr (std::is_same_v<std::remove_cvref_t<T>,Unit>){
              return Point3D(x.as<T>(),y.as<T>(),z.as<T>());
         }else{
              return Point3D(x,y,z);
         }
    }
    

    【讨论】:

    • 大体思路很扎实,但是代码不太对。 Unit 不是类型。理想情况下,这应该用一个概念来处理,但是is_unit_type&lt;T&gt;::value trait 类型会更向后兼容。
    • @Frank,Staz 提供的示例对我不起作用,我认为您是在暗示并提出更好的方法。但我不确定如何实现它。你能举个例子吗?谢谢
    • @MarkTwombley 我有点用Unit 作为类型的占位符。您可以相应地更换它。 std::remove_cvref 也是 C++20 类型特征。如果您的 cpp 标准低于 20,您可以改用 std::remove_cv_t&lt;std::remove_reference_t&lt;T&gt;&gt;
    • 感谢@Staz 的更新。我得到了它的工作。
    【解决方案2】:

    我会使用重载作为自定义点:

    // overload for built-in type (no ADL)
    double to_double(double d) { return d;}
    
    template <typename T>
    struct XYZVector
    {
        // ...
        operator Point3D() const {
            return Point3D(to_double(x),
                           to_double(y),
                           to_double(z));
        }
    };
    
    // The ones which can be found by ADL can be placed after
    namespace Unit {
        double to_double(usFoot u) { return u.as<double>(); } 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2021-08-30
      相关资源
      最近更新 更多