2009-11-17 35 views
8

我有使用模板和陣列尺寸爲模板非類型參數下面的代碼C++中數組維度

template<int n> double f(double c[n]); 
... 
double c[5]; 
f<5>(c); // compiles 
f(c); // does not compile 

不應編譯器能夠實例化而不顯式模板參數的第二fθ模板參數?我正在使用g ++ 4.1

+0

MSVC會讓你逃脫謀殺。 – 2009-11-17 01:06:50

+0

VC8不會 - 至少不會與理智的設置:) – 2009-11-17 01:08:06

+0

我錯了。 MSVC可以讓你做double(&c)[n]這顯然不是一回事。雙(&c)[n] Comeau也很酷。令人驚訝的是,有幾個人會產生差異。 – 2009-11-17 01:10:49

回答

28

它的工作原理:

template<size_t n> double f(double (&c)[n]); 
+0

謝謝這正是我一直需要的 – Anycorn 2009-11-17 02:23:31

1

不幸的是,因爲當你將double c[5]傳遞給f(),或者任何數組傳遞給任何需要數組的函數時,你將失去大小信息。你只傳遞一個指針。

編輯:但請參閱gf的解決方法的答案。

+2

您的評論雖然正確無關。確實,在運行時無法確定數組的大小,但模板參數推導發生在編譯時。編譯器知道數組的大小是5,並可以相應地推導出模板參數,儘管這有一些限制。 – boycy 2011-08-17 12:45:53

+0

運行時無法確定* any *原語的原始聲明類型。當您將它傳遞給需要指針的函數時,您確實會丟失信息,但當您將float傳遞給需要整數的函數時,您將以與丟失信息相同的方式丟失信息。更具體地說,聲明時的數組類型是「5個雙精度數組」,或double [5]。大小數組類型對指針具有隱式轉換。這種轉換很常見,我們傾向於忘記它不是數組的原始類型,但它與其他類型一樣有效。 – 2015-09-30 20:10:40

0

不,因爲在不同的調用中,參數可能來自任何地方。編譯器肯定無法在運行時追逐指針

編輯:順便說一句,這對我的作品,但需要-std = C++ 0x中使用引用時(我用gcc 4.4)

#include <iostream> 

template <int n> 
struct T 
{ 
    T& 
    operator=(double const cc[n]) 
    { 
     c = cc; 
     return *this; 
    } 
    const double 
    operator[](int const &i) 
    { 
     return c[i]; 
    } 
    double c[n]; 
}; 

template<int n> 
double 
f(T<n> & x) 
{ 
    return x[n-1]; 
} 

int 
main() 
{ 
    T<5> t5 = {10, 20, 30, 40, 50}; 
    T<3> t3 = {100, 200, 300}; 
    std::cout << f(t5) << std::endl; 
    std::cout << f(t3) << std::endl; 
    return 0; 
} 
-1

這可以幫助你解決更大的問題(不管可能如何)。這將允許您在編譯時查詢數組的大小/類型。

template < typename T_, unsigned N_ > 
class many { 
public: 
    typedef T_ T; 
    enum { N = N_ }; 

    T array[N]; 
}; 

賈斯汀

+0

呃?這有什麼幫助? – bobbogo 2017-11-16 15:47:55