-2

I see one constructor of class so strange:

class HashTable
{
public:
    template <int N>
    HashTable(const char(&str)[N])

    {
    }
};

Could you please explain it and some example or give me a related link? I really don't understand const char(&str)[N].

L. F.
  • 19,445
  • 8
  • 48
  • 82
ledien
  • 529
  • 2
  • 8
  • 19
  • 1
    what part dont you understand? Do you know about templates? Do you know what `const char(&str)[N]` is ? Please try to be more specific – 463035818_is_not_an_ai May 22 '19 at 09:24
  • 5
    honestly, its not a good strategy to write a question each time you encounter a piece of code you dont understand as your first goto solution. Maybe take a look here https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list – 463035818_is_not_an_ai May 22 '19 at 09:29
  • didnt find a good duplicate, but this is very related: https://stackoverflow.com/questions/2188991/what-is-useful-about-a-reference-to-array-parameter and if you browse the answers you also find one that explains the template trick to get the size of the array – 463035818_is_not_an_ai May 22 '19 at 09:35
  • What you want to know on const char(&str)[N]. Cannot understan this small code – Arun May 22 '19 at 09:58

1 Answers1

5

This is a way to capture the size of an array parameter. Arrays have a type of T[N] that often can decay to T*.

#include <iostream>

template <int N>
void foo(const char(&str)[N]){
    for(int i=0;i<N;++i)
        std::cout<<str<<' ';
}

void foo(const char* str){
    //for(int i=0;i<??;++i)
}

void bar(const char* str, int n){
    for(int i=0;i<n;++i)
        std::cout<<str<<' ';
}
int main(){
    const char str[] =  "Hello";//type is const char[6]
    const char* str2 = str; //Decay
    // const char str3[] = str; (6)
    int n = sizeof(str)/sizeof(str[0]);
    foo(str);// (1) Calls foo<6>
    foo(str2);// (2) Must call foo(const char*) which is useless
    bar(str, n); // (3) Array can decay
    bar(str2, n); // (4) Same as (3) - bar can be used with all arrays
    bar(str2, 10); // (5) Buffer overrun
}

The above example shows the usage and limitation of the templated approach. The advantage is that you don't have to pass the size separately so it will be always be correct. The big disadvantage is that the decay process is irreversible so the function then becomes useless - (2) cannot call the template.

The template is handy but most arrays decay to pointers rather quickly by passing them around via bar - which was the only way in C - or simply because their size is not known at compile time - malloc, new. Another problem is that both in C and C++ (6) is invalid - there's no implicit way to copy an array. So the bar approach is much more common but it requires extra care to pass the correct size. The correct c++ way is to use std::vector or std::array unless they are proven to be a bottleneck.

Quimby
  • 17,735
  • 4
  • 35
  • 55