具有模板参数大小与char指针的Const char数组

sta*_*anm 5 c++ templates pointers c++11

我今天在一些代码中看到了以下类型的结构:

template<unsigned int N> unsigned int f(const char (&a)[N]);
Run Code Online (Sandbox Code Playgroud)

有没有任何合理的观点来解决这个问题:

unsigned int f(const char *a);
Run Code Online (Sandbox Code Playgroud)

我模糊地理解后者的指针共享含义,但实际上是非常糟糕的,它需要被两倍大小的模糊代码所取代吗?

(不幸的是,我不能问作者的代码,否则我会)

Who*_*aig 13

将任何原始指针传递给函数的意图是调用者有一些想法:

  • 它指向的是什么.
  • 有多少指向.

作为输入参数的C样式字符串具有后者推断,因为假设通过到达null char终止符来认为"多少".

但是,如果你没有传递C风格的字符串怎么办?如果它只是一个零或更多char值的序列怎么办?好吧,如果是这样的话,那么:

void f(const char *s)
{
    // how many char does s refer to?
}
Run Code Online (Sandbox Code Playgroud)

逻辑演绎将是这样做的:

void f(const char *s, std::size_t N)
{
    // Now the caller is telling us there are N chars at s
}
Run Code Online (Sandbox Code Playgroud)

这种情况并不少见,尽管如果调用者传给我们错误的长度(从不说永远),可能会出现错误.

但是如果有一种方法可以通过非类型模板参数使用演绎将实际变量类型的数据传递给函数呢?如果调用者使用固定数组调用我们该怎么办?

template<std::size_t N>
void f(const char(&ar)[N])
{
    // we know the caller is passing a const-reference to a
    // char array declared of size N. The value N can be used
    // in this function.
}
Run Code Online (Sandbox Code Playgroud)

现在我们知道列表中的两个项目:"什么"和"多少".此外,我们现在可以提供两种模板功能和过载,并有提供给我们的两个世界:

// length specified implementation
void f(const char *s, std::size_t N)
{
    // caller passed N
}

// fixed buffer template wrapper
template<std::size_t N>
void f(const char(&ar)[N])
{
    f(ar,N); // invokes length-specified implementation from above.
}
Run Code Online (Sandbox Code Playgroud)

以下两种方法都有效:

int main()
{
    char buff[3];

    f(buff,3);
    f(buff);

}
Run Code Online (Sandbox Code Playgroud)

那怎么这么好?因为以下将标记编译器错误,因为找不到匹配的实现:

int main()
{
    char buff[3];
    const char *ptr = buff;
    f(ptr); // ERROR: no matching function f(const char *)
}
Run Code Online (Sandbox Code Playgroud)

总之,这是一种常见的技术,可以帮助我们将子弹列表中的项目提供给被调用者:"what"和"多少",而不必sizeof(ar)/sizeof(*ar)每次使用固定长度的本机数组时都需要长时间操作输入参数.

祝你好运.