why does the array decay to a pointer in a template function

前端 未结 5 887
抹茶落季
抹茶落季 2020-12-16 04:24

I don\'t understand why the array decays to a pointer in a template function.

If you look at the following code: When the parameter is forced to be a reference (fun

相关标签:
5条回答
  • 2020-12-16 04:56

    To quote from spec, it says

    (14.8.2.1/2) If P is not a reference type: — If A is an array type, the pointer type produced by the array-to-pointer standard conversion (4.2) is used in place of A for type deduction; otherwise

    So, in your case, It is clear that,

    template <class T>
    void f1(T& buff) {
        std::cout << "f:buff size:" << sizeof(buff) << std::endl;       //prints 3
    }
    

    doesn't decay into pointer.

    0 讨论(0)
  • 2020-12-16 05:16

    The reason basically boils down to type deduction when matching the different overloads. When you call f the compiler deduces the type to be const char[3] which then decays into const char* because that's what arrays do. This is done in the same exact way that in f(1) the compiler deduces T to be int and not int&.

    In the case of f1 because the argument is taken by reference, then the compiler again deduces T to be const char[3], but it takes a reference to it.

    Nothing really surprising, but rather consistent if it were not for the decay of arrays to pointers when used as function arguments...

    0 讨论(0)
  • 2020-12-16 05:20

    Because functions can't have arrays as arguments. They can have array references though.

    0 讨论(0)
  • 2020-12-16 05:22

    Because arrays can not be passed by value as a function parameter.
    When you pass them by value they decay into a pointer.

    In this function:

    template <class T>
    void f(T buff) {
    

    T can not be char (&buff)[3] as this is a reference. The compiler would have tried char (buff)[3] to pass by value but that is not allowed. So to make it work arrays decay to pointers.

    Your second function works because here the array is passed by reference:

    template <class T>
    void f1(T& buff) {
    
    // Here T& => char (&buff)[3]
    
    0 讨论(0)
  • 2020-12-16 05:22

    It is because arrays cannot be passed by value to a function. So in order to make it work, the array decays into a pointer which then gets passed to the function by value.

    In other words, passing an array by value is akin to initializing an array with another array, but in C++ an array cannot be initialized with another array:

    char buff[3] = {0,0,0};
    char x[3] = buff; //error 
    

    So if an array appears on the right hand side of =, the left hand side has to be either pointer or reference type:

    char *y = buff; //ok - pointer
    char (&z)[3] = buff; //ok - reference
    

    Demo : http://www.ideone.com/BlfSv

    It is exactly for the same reason auto is inferred differently in each case below (note that auto comes with C++11):

    auto a = buff; //a is a pointer - a is same as y (above)
    std::cout << sizeof(a) << std::endl; //sizeof(a) == sizeof(char*)
    
    auto & b = buff; //b is a reference to the array - b is same as z (above)
    std::cout << sizeof(b) << std::endl; //sizeof(b) == sizeof(char[3])
    

    Output:

    4 //size of the pointer
    3 //size of the array of 3 chars
    

    Demo : http://www.ideone.com/aXcF5

    0 讨论(0)
提交回复
热议问题