2016-04-10 41 views
1

我正在观看Youtube上的视频,它展示了新标准(C++ 11,C++ 14)的各种特性。带列表参数的和函数C++ 11/C++ 14风格

我知道,在C是建立一个可变参数的功能类似于一个机会:

#include <stdarg.h> 
#include <stdio.h> 

double average(int count, ...) 
{ 
    va_list ap; 
    int j; 
    double sum = 0; 

    va_start(ap, count); /* Requires the last fixed parameter (to get the address) */ 
    for (j = 0; j < count; j++) { 
     sum += va_arg(ap, int); /* Increments ap to the next argument. */ 
    } 
    va_end(ap); 

    return sum/count; 
} 

int main(int argc, char const *argv[]) 
{ 
    printf("%f\n", average(3, 1, 2, 3)); 
    return 0; 
} 

录像显示下面的例子:

struct Sum 
{ 
    template <typename T> 
    static T sum(T n) 
    { 
     return n; 
    } 

    template <typename T, typename... Args> 
    static auto sum(T n, Args ... rest) -> decltype(n + sum(rest...)) 
    { 
     return n + sum(rest...); 
    } 
}; 

我使用的代码一样,第二束:

int main() 
{ 

    int suma = Sum::sum(1, 2, 3, 4, 5, 6); 
    cout << suma; 

    return 0; 
} 

而我发现它完全可行,所以它真的很棒。但我没有收到警告:

(活动)没有重载函数“总和::总和”的实例参数列表匹配

我的问题是:哪一种方法更好,我怎么能在第二个摆脱警告?

+0

你是什么编译使用? – HolyBlackCat

+0

我正在使用Visual Studio 2015内置的编译器,我试图检查什么是编译器的版本,但是我找不到它在哪里编写。 – FieryCod

+0

我不认为可变参数函数是好的,因为它不是类型安全的,因此容易产生细微的错误。它可能是如何编码可变参数函数的一个很好的例子,但更强大的方法是传递一个数组,即'double avg(const int a [],size_t n)'。该签名还与数据通常用C表示的方式相匹配。如果您使用C++,请利用C++的模板功能。 –

回答

2

第一种方法是C,第二种方法是C++类型检查。

要修复在C++ 14的代码,删除尾随返回类型: Demo

C++ 1Z甚至允许折叠式:

template <typename ... Ts> 
static auto sum(Ts...args) 
{ 
    return (0 + ... + args); 
} 

Demo

+0

@Charlie:编辑后为C++ 14添加修复程序。 – Jarod42

+0

第一个演示完美。十分感谢。但是第二个在NetBeans 8.0中并不适用于新的标准。 – FieryCod