![](/img/trans.png)
[英]Use of (templated) deleted function overload to prevent usual arithmetic conversions
[英]Performing the usual arithmetic conversions for my own function?
今天就出現了,所以我想我會把它扔給社區。
一位同事編寫了以下代碼(或多或少):
#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(修復bug),以及(b)使用std::max
而不是myMax
(當你想到它時,它的行為非常可怕)。
但他想知道為什么會這樣。 我的意思是,他可以寫0 + x
或0 * x
或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 ++語言是否為我提供了一種簡單的方法來定義我自己的函數,該函數在其參數上執行與各種內置算術運算符相同的轉換?
除了Charles Bailey的回答,你也可以這樣做:
template<typename T1, typename T2>
typename std::common_type<T1, T2>::type max(T1&& a, T2&& b) {
return a < b ? b : a;
}
common_type
有一個typedef type
,它是兩個類型都可以隱式轉換為的類型,所以如果它是,例如, double
和int
,它將返回一個double
,但如果它是int
和int
,它將返回一個int
。
如果你根本不能使用C ++ 11,那么我唯一能想到的是:
template<typename T1, typename T2, typename T3>
void max(const T1& a, const T2& b, T3& dst) {
dst = a < b ? b : a;
}
並使用它
double d;
max(0, 43.12, d);
不過必須以這種方式聲明變量是非常笨拙的。 如果你認為它更漂亮,你也可以這樣做:
template<typename RetType, typename T1, typename T2>
RetType max(const T1& a, const T2& b) {
return a < b ? b : a;
}
接着
return max<double>(0, 43.11);
我不知道在C ++ 11之前的好方法,但現在你可以做這樣的事情。
template<class T, class U>
auto myMax(T&& t, U&& u) -> decltype(t + u)
{
return t < u ? u : t;
}
decltype(t + u)
只計算出T
和U
的常用類型在算術表達式中的含義,並將其用作模板的返回類型。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.