C++ - 如何在不重载比较运算符的情况下为 std::max 专门化自定义类型?
C++ - How to specialise a custom type for std::max without overloading comparison operators?
我正在寻找有关如何为自定义数据类型实现专门的 "max"(即最大)函数的建议,该函数也适用于 float
等标量类型。我正在编写的数据类型是向量的包装器(最终是四个浮点数的 SIMD 向量,而不是 std::vector
),我想提供一个 max
函数来比较两个向量和 return 一个新向量,它是每个元素的最大值。这与使用比较运算符的 std::max
不同,但概念相同。
问题是我有一个名为 do_max(T x, T y)
的通用函数,它将 max
应用于输入。我需要此函数适用于两个标量浮点输入(例如 do_max<float>(0.1f, 0.2f)
) 和 我的矢量 class(例如 do_max<MyVector>(v0, v1)
)。
请注意,重载 MyVector 的比较运算符不是一种选择,因为我使用的是具有完全不同的 SIMD 内在函数的那些运算符:它们为每个元素比较创建一个包含 1、0、-1 的整数向量,而不是 return 一个布尔结果。
除非您注释掉 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
,以及我专门的 max
MyVector 类型的友元函数。
如何定义以这种方式工作的 max 函数?忘记 std::max
并使用我自己的专用于 MyVector
的 max 函数是否更好,并且还为 float
?
等标量类型提供实现
这样做的背景是我正在实现一个数据路径,我希望它能与 MyVector 和标量类型一起工作(作为编译时的参数化类型)。我已经有了算术运算,但是 max
的解决方案也将与其他函数一起使用,例如 min
、exp
、pow
。
经典解法:
template<typename T>
T do_max(const T & x, const T & y) {
using std::max;
return max(x, y);
}
Argument-Dependent Lookup 找到您的 max
,因为 float
这不会发生,您得到 std::max<float>
.
我正在寻找有关如何为自定义数据类型实现专门的 "max"(即最大)函数的建议,该函数也适用于 float
等标量类型。我正在编写的数据类型是向量的包装器(最终是四个浮点数的 SIMD 向量,而不是 std::vector
),我想提供一个 max
函数来比较两个向量和 return 一个新向量,它是每个元素的最大值。这与使用比较运算符的 std::max
不同,但概念相同。
问题是我有一个名为 do_max(T x, T y)
的通用函数,它将 max
应用于输入。我需要此函数适用于两个标量浮点输入(例如 do_max<float>(0.1f, 0.2f)
) 和 我的矢量 class(例如 do_max<MyVector>(v0, v1)
)。
请注意,重载 MyVector 的比较运算符不是一种选择,因为我使用的是具有完全不同的 SIMD 内在函数的那些运算符:它们为每个元素比较创建一个包含 1、0、-1 的整数向量,而不是 return 一个布尔结果。
除非您注释掉 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
,以及我专门的 max
MyVector 类型的友元函数。
如何定义以这种方式工作的 max 函数?忘记 std::max
并使用我自己的专用于 MyVector
的 max 函数是否更好,并且还为 float
?
这样做的背景是我正在实现一个数据路径,我希望它能与 MyVector 和标量类型一起工作(作为编译时的参数化类型)。我已经有了算术运算,但是 max
的解决方案也将与其他函数一起使用,例如 min
、exp
、pow
。
经典解法:
template<typename T>
T do_max(const T & x, const T & y) {
using std::max;
return max(x, y);
}
Argument-Dependent Lookup 找到您的 max
,因为 float
这不会发生,您得到 std::max<float>
.