使用模板专业化来区分值和数组(值)

时间:2011-04-28 17:28:56

标签: c++

我正在尝试构建一个设备,它将为一个值(特别是本机类型)做一件事,而对于一个C风格的基元数组则做另一件事。

这就是我现在所拥有的,这不符合我的意愿。

#include <cstdlib>
#include <string>
#include <iostream>
#include <iomanip>

using namespace std;

template<class V> void dump_buf(const V& val)
{
    cout << "val = " << val << "\n";
}

template<class A> void dump_buf(const A ary[])
{
    cout << "ary size = " << sizeof(ary) << "\n";
    for( size_t i = 0; i < sizeof(ary); ++i )
        cout << "\t" << i+1 << " : " << ary[i] << "\n";
}

int main()
{
    cout << "\n";
    int i = 42;
    float f = 3.14f;
    unsigned fib[] = {0,1,1,2,3,5};
    char s[] = "hello";
    dump_buf(i);
    dump_buf(f);
    dump_buf(s);
    dump_buf(fib);
}

这不起作用,因为ary是指向某事物的类型,而不是某种数组。上面的输出(Intel,x64 compile,VS9)是:

val = 42
val = 3.14
ary size = 8
        1 : h
        2 : e
        3 : l
        4 : l
        5 : o
        6 :
        7 : ╠
        8 : ╠
ary size = 8
        1 : 0
        2 : 1
        3 : 1
        4 : 2
        5 : 3
        6 : 5
        7 : 3435973836
        8 : 3435973836

但我希望输出为:

val = 42
val = 3.14
ary size = 6
        1 : h
        2 : e
        3 : l
        4 : l
        5 : o
        6 :
ary size = 6
        1 : 0
        2 : 1
        3 : 1
        4 : 2
        5 : 3
        6 : 5

请注意,字符串的所需输出是6个字符而不是5个字符,因为null-terminator是数组的一部分。

有没有办法让它工作,只使用标准C ++而没有其他库?

几乎任何符合标准的技术都是可以接受的。重载,模板专业化,覆盖,类模板......一切都好。我对几乎任何可以实现我的目标的技术持开放态度。

1 个答案:

答案 0 :(得分:3)

这应该可以解决问题:

template<class A, size_t S> void dump_buf(const A (& ary)[S])
{
    cout << "ary size = " << S << "\n";
    for( size_t i = 0; i < S; ++i )
        cout << "\t" << i+1 << " : " << ary[i] << "\n";
}

通过引用数组而不是指向数组开头的指针,大小是已知的并且可用作推断的模板参数。

另外,请记住sizeof给出了字节大小,所以当你想要一个数组中的对象数量(并且不能或不想使用这样的模板)时,你想要的sizeof(ary)/sizeof(*ary)。在这两种情况下,你需要一个真正的数组,而不是一个指向数组的指针,它已经失去了对数组大小的所有了解。