我希望有人可以解释以下行为。
假设我正在尝试实现一个确定任何数组长度的函数,但希望避免使用宏。例如
#define array_length(x) ( sizeof(x) / sizeof(x[0]) )
鉴于该函数必须适用于任何参数类型,我必须使用模板。
我的第一次尝试看起来像这样。
template <typename T>
inline size_t
array_length(const T argument) {
return sizeof(argument) / sizeof(argument[0]);
}
这不起作用,因为参数被视为指针。一旦T改为T&amp;一切都很有效。
我想知道是否有人可以就语言实施水平发生的事情说些什么。例如,当引用用作函数参数时,将哪些额外信息传递给函数?
答案 0 :(得分:5)
让我们考虑两个功能模板:
template <typename T> void f(T);
template <typename T> void g(T const&);
让我们说我们有一个数组:
int a[10];
当我们致电f(a);
时会发生什么?由于我们没有明确地为模板提供参数,因此参数推断会启动,编译器会尝试根据参数找出T
。参数类型为int[10]
。永远不会推断T
是引用类型,并且您不能按值传递数组,因此会发生数组到指针的隐式转换,并推导T
为int*
。
当我们致电g(a);
时会发生什么?同样,参数推导用于确定T
是什么。该参数的类型为 T
的引用,因此T
可以直接推导为int[10]
,并且数组到指针的转换不会的地方。
请注意,找到数组长度的最佳解决方案是明确要求模板获取数组:
template <typename T, std::size_t N>
std::size_t array_length(T const (&)[N]) { return N; }
答案 1 :(得分:2)
AFAIK没有好办法在宏之外做到这一点。这就是为什么我宁愿使用std::array
(C ++ 0x中的新类,从boost::array演化而来,也可用于“旧”C ++)或std::vector
。
答案 2 :(得分:1)
我知道你正在寻找更多的技术信息,但你可以使用模板参数推导得到数组中没有宏的元素数量:
template<typename T, size_t N>
size_t ElementCount(const T (&x)[N])
{
return N;
}
像这样使用:
int x[15];
size_t elements = ElementCount(x);