2009-11-17 22 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