Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is type deduction on const char[] different to const char *?

In the first call, when I pass a char const [] into a template function with a parameter of T const a, T is deduced as char const * which is reasonable because const refers to the decaying pointer.

However, when the parameter type is changed to T const & a, T is deduced as char[7]. From the point of view above, why doesn't the const qualify the whole array type?

template <typename T>
void show1(T const a) {
     // input is const char *
     // T is char const *
     // a is char const * const
}

template <typename T>
void show2(T const & a) {
     // input is char const [7]
     // T is char[7]
     // a is char const (&)[7]
}

int main() {
    const char s[] = "asdasd";
    show1(s);
    show2(s);
}
like image 610
BAKE ZQ Avatar asked Aug 12 '20 07:08

BAKE ZQ


People also ask

What is the difference between char * and const char *?

Simple: "char *name" name is a pointer to char, i.e. both can be change here. "const char *name" name is a pointer to const char i.e. pointer can change but not char.

What does const char * means?

const char *ptr : This is a pointer to a constant character. You cannot change the value pointed by ptr, but you can change the pointer itself. “const char *” is a (non-const) pointer to a const char.

Why do we use const char * in C?

In C programming language, *p represents the value stored in a pointer and p represents the address of the value, is referred as a pointer. const char* and char const* says that the pointer can point to a constant char and value of char pointed by this pointer cannot be changed.

Can a char * be passed as const * argument?

In general, you can pass a char * into something that expects a const char * without an explicit cast because that's a safe thing to do (give something modifiable to something that doesn't intend to modify it), but you can't pass a const char * into something expecting a char * (without an explicit cast) because that's ...


2 Answers

why doesn't the const qualify the whole array type

Because for array type,

(emphasis mine)

Applying cv-qualifiers to an array type (through typedef or template type manipulation) applies the qualifiers to the element type, but any array type whose elements are of cv-qualified type is considered to have the same cv-qualification.

// a and b have the same const-qualified type "array of 5 const char"
typedef const char CC;
CC a[5] = {}; 
typedef char CA[5];
const CA b = {};

That means when T is char[7] T const leads to the type char const[7], then T const& (i.e. a's type) is char const (&)[7].

On the other hand, when you pass the array s with type const char[7], the array is considered as const-qualified too. So given the parameter type T const&, T is deduced as char[7] (but not char const[7]).

like image 199
songyuanyao Avatar answered Oct 16 '22 16:10

songyuanyao


This is because arrays are non-copyable and non-assignable in C++.

So in calling show1, the const char[] type decays to a const char*. The language permits one implicit conversion per parameter at a function call site.

With show2, you are passing by reference - no copy or assignment is required, so pointer decay does not occur.

like image 30
Bathsheba Avatar answered Oct 16 '22 16:10

Bathsheba