簡體   English   中英

將不同類型的參數傳遞給函數模板

[英]Passing different types of parameters to a function template

考慮這個模板:

template<typename t>
t add(t a, t b) {
    return a+b;
}

如何傳遞不同類型的參數,以便返回值為:

  • int如果兩個參數都是int類型。

  • float如果參數中的一個是類型的float

  • float如果兩個參數的類型的float

我也嘗試過為模板設置多個參數:

template<typename t, typename c>

使用它們作為函數參數,因此它們可以是不同的( t add(ta, cb) )但是我t add(ta, cb)是我如何根據函數的類型(int,float,double等)來改變在返回類型?

使用自動類型推導(從c ++ 14開始):

template<typename t, typename u>
    auto add(t a, u b) {
        return a+b;
    }

你想要的是std::common_type

template<typename T0, typename T1>
typename std::common_type<T0, T1>::type add(T0 a, T1 b) {
    return a+b;
}

文件說明:

對於算術類型,可以將公共類型視為(可能是混合模式)算術表達式的類型,例如T0()+ T1()+ ... + Tn()。

但是,正如@ Jarod42在評論中指出的那樣,這只是一個視圖,在某些情況下可能是錯誤的:例如, std::common_type<char, char>::typechar而算術表達式char() + char()產生int


更完整的實現可以明確地轉換結果以消除上述情況中的可能警告:

template<typename T0, typename T1, typename R = std::common_type_t<T0, T1>>
R add(T0 a, T1 b) {
    return static_cast<R>(a+b);
}

這里std::common_type默認用於返回類型,但由於它是模板參數,因此在使用該函數時可以指定不同的類型(在更復雜的用例中可能有用):

char a = 1, b = 2;
add<decltype(a), decltype(b), int>(a, b);

使用std::conditionalstd::is_same ,@ Jarod42在注釋中提出的更完整的解決方案允許將模板R作為第一個參數,並保持對ab自動推導:

template <typename R, typename T0, typename T1>
using ResType = std::conditional_t<
    std::is_same<void, R>::value,
    std::common_type_t<T0, T1>, // default
    R                           // R was explicitly specified: use it
>;

template <typename R = void, typename T0, typename T1>
ResType<R, T0, T1> add(T0 a, T1 b)
{
    return static_cast<ResType<R, T0, T1>>(a + b);
}

用法:

char a = 1, b = 2;
add(a, b);       // returns char
add<int>(a, b);  // returns int

在c ++ 11及std::common_type ,您可以使用std::common_type

template<typename T1, typename T2>
auto add(T1 a, T2 b) -> typename std::common_type<T1, T2>::type {
  return a + b;
}

如同在Piotr的回答中一樣,它將起到整體促銷的作用,與僅僅進行auto類型演繹沒有多大區別。 但是,如果您嘗試將自定義類型作為參數傳遞,例如std::complex類,它將真正開始閃耀。


我寧願保留標准所強加的整體推廣類型,所以也許這應該包含在另一個特征中。

template<typename T1, typename T2>
class AdditionTraits {
  using common_t = typename std::common_type<T1, T2>::type;
  constexpr static bool is_char = std::is_same<common_t, char>::value;
public:
  using type = typename std::conditional<is_char, int, common_t>::type;
};

template<typename T1, typename T2>
auto add(T1 a, T2 b) -> typename AdditionTraits <T1, T2>::type {
  return a + b;
}

可以看到它將char添加到int ,正如標准的促銷規則那樣。

暫無
暫無

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

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