使用模板特化来区分值和数组(值的数组)

Using Template Specialization To Discriminate Between Values And Arrays (of Values)

本文关键字:数组      更新时间:2023-10-16

我正在尝试构建一个设备,它将为值(特别是本机类型)做一件事,为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编译,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个,因为空终止符是数组的一部分。

是否有办法让这个工作,只使用标准c++和没有额外的库?

几乎任何符合标准的技术都是可以接受的。重载、模板专门化、重写、类模板……一切都好。

我对任何能达到我目标的方法都持开放态度。

这应该能奏效:

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)。在这两种情况下,您都需要一个真正的数组,而不是指向数组的指针,因为它已经丢失了数组大小的所有信息。