2016-04-10 46 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