2014-10-12 41 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...>; 

应该做的伎俩。

也许会增加衰减。

相关问题