简体   繁体   English

如何在不重载比较运算符的情况下专门针对std :: max自定义类型?

[英]C++ - How to specialise a custom type for std::max without overloading comparison operators?

I'm looking for advice on how to implement a specialised "max" (ie maximum) function for a custom data type that also works with scalar types like float . 我正在寻找有关如何为自定义数据类型实现专门的“最大”(即最大)功能的建议,该功能也可与标量类型(如float The data type I'm writing is a wrapper for a vector (eventually a SIMD vector of four floats, not a std::vector ) and I want to provide a max function to compare two vectors and return a new vector that is the maximum of each element. 我正在写的数据类型是向量的包装器(最终是四个浮点数的SIMD向量,而不是std::vector ),并且我想提供一个max函数来比较两个向量并返回最大的新向量每个元素。 This is different to std::max which uses the comparison operator but the concept is the same. 这与使用比较运算符的std::max不同,但概念相同。

The problem is that I have a generic function called do_max(T x, T y) that applies max to the inputs. 问题是我有一个名为do_max(T x, T y)的通用函数,该函数将max应用于输入。 I need this function to work for both scalar float inputs (eg do_max<float>(0.1f, 0.2f) ) and my vector class (eg do_max<MyVector>(v0, v1) ). 我需要此函数同时用于标量浮点输入(例如do_max<float>(0.1f, 0.2f)我的向量类(例如do_max<MyVector>(v0, v1) )。

Note that overloading MyVector's comparison operators is not an option because I'm using those with the SIMD intrinsics that are quite different: they create an integer vector containing 1, 0, -1 for each element comparison rather than returning a boolean result. 请注意,重载MyVector的比较运算符不是一种选择,因为我使用的SIMD内在函数完全不同:它们为每个元素比较创建一个包含1、0,-1的整数矢量,而不是返回布尔结果。

The code I have below does not compile unless you comment out the float f0 = ... line: 除非您注释掉float f0 = ...行,否则我下面的代码不会编译:

// compile with: g++ -std=c++11 max.cc -o max
#include <algorithm>
#include <vector>

class MyVector {
public:
  MyVector(float x0, float x1, float x2, float x3) : storage_ { x0, x1, x2, x3 } {};

  friend MyVector max(MyVector lhs, const MyVector & rhs);

private:
  std::vector<float> storage_;
};

MyVector max(MyVector lhs, const MyVector & rhs) {
  for (size_t i = 0; i < lhs.storage_.size(); ++i) {
    lhs.storage_[i] = std::max(lhs.storage_[i], rhs.storage_[i]);
  }
  return lhs;
}

template<typename T>
T do_max(const T & x, const T & y) {
  // if this is std::max then it won't compile for MyVector
  return max(x, y);
}

int main(int argc, char * argv[]) {

  MyVector v0 { 0.1, 0.2, 0.3, 0.4 };
  MyVector v1 { 0.4, 0.3, 0.2, 0.1 };

  MyVector v2 = do_max(v0, v1);

  // Comment out the following line to successfully compile.
  // However I'd like this to work for scalar types too:
  float f0 = do_max(0.1f, 0.2f);

  return 0;
}

I have a feeling I need a way to make that max function resolve to std::max for scalar types, and my specialised max friend function for the MyVector type. 我有一种感觉,我需要一种方法来使max函数解析为标量类型的std::max ,以及我专用的MyVector类型的max friend函数。

How to I define a max function that works in this way? 如何定义以这种方式工作的max函数? Is it better to forget about std::max and use my own max function that is specialised for MyVector and also provides implementation for scalar types like float ? 最好忘掉std::max并使用我自己的max函数,该函数专门用于MyVector并且还为float等标量类型提供实现?

The background for this is that I'm implementing a data path that I hope will work with both MyVector and scalar types (as a parameterised type at compile time). 这样做的背景是,我正在实现一个数据路径,希望它可以同时使用MyVector和标量类型(在编译时作为参数化类型)。 I already have arithmetic working, however the solution for max will be used with other functions like min , exp , pow as well. 我已经进行过算术运算,但是max的解决方案也将与minexppow等其他函数一起使用。

Classic solution: 经典解决方案:

template<typename T>
T do_max(const T & x, const T & y) {
  using std::max;
  return max(x, y);
}

Argument-Dependent Lookup finds your max , for float this does not happen and you get std::max<float> . 基于参数的查找会找到您的max ,对于float不会发生,您会得到std::max<float>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM