簡體   English   中英

為我自己的函數執行通常的算術轉換?

[英]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 + x0 * x0 - 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 ,它是兩個類型都可以隱式轉換為的類型,所以如果它是,例如, doubleint ,它將返回一個double ,但如果它是intint ,它將返回一個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)只計算出TU的常用類型在算術表達式中的含義,並將其用作模板的返回類型。

暫無
暫無

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

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