簡體   English   中英

如何在不重載比較運算符的情況下專門針對std :: max自定義類型?

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

我正在尋找有關如何為自定義數據類型實現專門的“最大”(即最大)功能的建議,該功能也可與標量類型(如float 我正在寫的數據類型是向量的包裝器(最終是四個浮點數的SIMD向量,而不是std::vector ),並且我想提供一個max函數來比較兩個向量並返回最大的新向量每個元素。 這與使用比較運算符的std::max不同,但概念相同。

問題是我有一個名為do_max(T x, T y)的通用函數,該函數將max應用於輸入。 我需要此函數同時用於標量浮點輸入(例如do_max<float>(0.1f, 0.2f)我的向量類(例如do_max<MyVector>(v0, v1) )。

請注意,重載MyVector的比較運算符不是一種選擇,因為我使用的SIMD內在函數完全不同:它們為每個元素比較創建一個包含1、0,-1的整數矢量,而不是返回布爾結果。

除非您注釋掉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;
}

我有一種感覺,我需要一種方法來使max函數解析為標量類型的std::max ,以及我專用的MyVector類型的max friend函數。

如何定義以這種方式工作的max函數? 最好忘掉std::max並使用我自己的max函數,該函數專門用於MyVector並且還為float等標量類型提供實現?

這樣做的背景是,我正在實現一個數據路徑,希望它可以同時使用MyVector和標量類型(在編譯時作為參數化類型)。 我已經進行過算術運算,但是max的解決方案也將與minexppow等其他函數一起使用。

經典解決方案:

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

基於參數的查找會找到您的max ,對於float不會發生,您會得到std::max<float>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM