今天在工作中出现了这个问题,所以我想我会把它扔给社区。
一位同事(或多或少)编写了以下代码:
#include <algorithm>
double chop(double x) {
return std::max(0, x);
}
但这甚至无法编译,因为std::max
希望它的两个参数具有完全相同的类型。我相信这是因为它可以获取一对引用并返回一个引用,如果您在用户定义的类型上调用它,这很可能是您想要的。很公平。
当然,解决方法是使用std::max(0.0, x)
.
现在请容忍我一会儿,因为我撒了谎。我的同事实际上写的是这样的:
// Included from a very old header file written by someone long gone
template<class T1, class T2>
inline T1 myMax(T1 x, T2 y) {
return (x < y) ? y : x;
}
double chop(double x) {
return myMax(0, x);
}
这编译!但是对于 x 等于 0.25,它会产生相当令人惊讶的结果。我不知道他花了多长时间才找到问题,即使找到了,他也不得不问为什么它不起作用。
我的回答是(a)使用 0.0 而不是 0(修复了错误),以及(b)使用std::max
而不是myMax
(当你想到它时,它的行为是相当可怕的)。
但他想知道为什么会这样。我的意思是,他可以写0 + x
or 0 * x
or 0 - x
,那为什么不myMax(0, x)
呢?
这是我第一次给他他想要的东西:
// this is from the .hh file
// template meta-program to compute the "wider" of two types given as argument
template<class T1, class T2>
struct WiderType {
};
// Partial specialization for case where both types are same
template<class T>
struct WiderType<T, T> {
typedef T type;
};
// Specialization for first type "int" and second type "double"
template<>
struct WiderType<int, double> {
typedef double type;
};
template<class T1, class T2>
inline typename WiderType<T1,T2>::type
myMax(T1 a, T2 b) {
return ((a < b) ? b : a);
}
// this is from the .cc file
double chop(double x) {
return myMax(0, x);
}
// just to show this still works
int chop(int x) {
return myMax(0, x);
}
现在,我可以WiderType
为每一对整数类型添加一个特化,再加上一些来做其他通常的算术转换。(我想我可以重命名它UsualConversions
或类似的东西。)
但是有没有更简单的方法?也就是说,C++ 语言是否为我提供了一种简单的方法来定义我自己的函数,该函数对其参数执行与各种内置算术运算符相同的转换?