2014-10-12 85 views
1

我與可變參數模板玩,我只能堅持以下幾點:可變參數函數 - 確定返回類型

template <class T1, class T2> 
auto sum(T1 a, T2 b) ->decltype(a + b){ 
    return a + b; 
} 
template <class T1, class T2, class... T3> 
auto sum(T1 a, T2 b, T3... tail) ->decltype(a + b){ 
    return a + sum(b, tail...); 
} 

函數調用:

cout << sum(1, 2, 3, 4) << endl; // 10 - OK 
cout << sum(1.5, 2, 3, 4) << endl; // 10.5 - OK 
cout << sum(1, 2, 3.5, 4) << endl; // 10 !! wrong result 

我在做什麼錯在這裏?

+3

除非我在這裏丟失了一些東西,返回類型是'a + b'的類型。這裏'a'是'1','b'是'2',所以返回類型是'int'。 – NPE 2014-10-12 11:56:33

+0

我試圖寫decltype(a + tail ..)但是不起作用.. – Tracer 2014-10-12 11:57:39

+0

@Tracer:「我試圖寫decltype(a + tail ..)但是不起作用..」 - 通過嘗試這樣做,你的問題已經等同於這一個:http://stackoverflow.com/questions/26274207/gcc-can-compile-a-variadic-template-while-clang-cannot – 2014-10-12 12:09:09

回答

6
sum(1, 2, 3.5, 4) 

前兩個參數的類型爲int。因此,在追蹤返回類型中,decltype(a + b)int,所以結果被轉換爲int - 並被截斷。

使用std::common_type

template <class T1, class T2, class... T3> 
typename std::common_type<T1, T2, T3...>::type 
    sum(T1 a, T2 b, T3... tail) 
{ 
    return a + sum(b, tail...); 
} 

注意

template <class T1, class T2, class... T3> 
auto sum(T1 a, T2 b, T3... tail) ->decltype(a + sum(b, tail...)) 

,因爲這第二個模板不拖尾返回類型已知的,只有第一個不工作。隨着C++ 14,返回類型推演可能,但:

template <class T1, class T2, class... T3> 
auto sum(T1 a, T2 b, T3... tail) 
{ 
    return a + sum(b, tail...); 
} 
+0

在VS 2013中,我可以使用這兩個例子,但鐺不會編譯使用auto&decltype的第二個。那麼,第二種情況是C++ 14功能? – Tracer 2014-10-12 12:19:05

+0

爲此使用'common_type'的限制是它不適用於類類型。 – 2014-10-12 12:31:22

+0

@ T.C。你是對的。我可能想總結一下'string's。 – Columbo 2014-10-12 12:32:45

0
namespace details{ 
    template<template<class,class>class binary_result, class T, class...Ts> 
    struct nary_result{using type=T}; 
    template<template<class,class>class binary_result, class T0, class T1, class...Ts> 
    struct nary_result<binary_result, T0,T1,Ts...>: 
    nary_result<binary_result,binary_result<T0,T1>,Ts...> 
    {}; 
} 
template<template<class,class>class binary_result, class...Ts> 
using nary_result=typename details::nary_result<binary_result,Ts...>::type; 

template<class Lhs, class Rhs> 
using binary_sum_result = decltype(std::declval<Lhs>()+std::declval<Rhs>()); 

template<class...Ts> 
using sum_result=nary_result<binary_sum_result,Ts...>; 

應該做的伎倆。

也許會增加衰減。