What does char [5] const &
mean?
Constant lvalue reference to array of 5 char
Or lvalue reference to array of 5 constant char
Or lvalue reference to const array of 5 char?
I am reading C++ programming language book and I am learning about pointer to char. I found this code: char s[] = "Gorm";
, which reminds me that string literal is converted implicitly to const char *
.
So, I felt confused that LHS and RHS are not of same type.
I used online compiler and code from here to get idea about how compiler see type of LHS and RHS. Then, I found that LHS is seen as char[5]
while RHS is seen as char[5] const &
.
I can interpret LHS but, I cannot understand what is "constant lvalue reference to array of 5 char" or even after implicit conversion of LHS char s[]
to char* s
, what is "constant lvalue reference to non const pointer to non const char"?
Is not lvalue reference by definition constant "it refers only to value initializing it"? So, why do we need const
before &
?
And then, how can LHS and RHS of different types be assigned?
Following is the code, I used to get type of LHS and RHS:
#include < type_traits >
#include < typeinfo >
#ifndef _MSC_VER
#include < cxxabi.h >
#endif
#include < memory >
#include < string >
#include < cstdlib >
#include < iostream > // std::cout
template < class T > std::string
type_name() {
typedef typename std::remove_reference < T >:: typeTR;
std::unique_ptr < char, void( *)(void *) > own(#ifndef _MSC_VER abi::__cxa_demangle(typeid(TR).name(), nullptr, nullptr, nullptr), #else nullptr, #endif std::free);
std::string r = own != nullptr
? own.get()
: typeid(TR).name();
if (std::is_const < TR >:: value)
r += " const";
if (std::is_volatile < TR >:: value)
r += " volatile";
if (std::is_lvalue_reference < T >:: value)
r += "&";
else if (std::is_rvalue_reference < T >:: value)
r += "&&";
return r;
}
int & foo_lref();
int && foo_rref();
int foo_value();
int main() {
int i = 0;
const int ci = 0;
char s[] = "Gorm";
std::cout << "decltype(s) is " << type_name < decltype("Gorm") > () << '\n';
std::cout << "decltype(i) is " << type_name < decltype(i) > () << '\n';
std::cout << "decltype((i)) is " << type_name < decltype((i)) > () << '\n';
std::cout << "decltype(ci) is " << type_name < decltype(ci) > () << '\n';
std::cout << "decltype((ci)) is " << type_name < decltype((ci)) > () << '\n';
std::cout << "decltype(static_cast<int&>(i)) is " << type_name < decltype(static_cast < int &> (i)) > () << '\n';
std::cout << "decltype(static_cast<int&&>(i)) is " << type_name < decltype(static_cast < int &&> (i)) > () << '\n';
std::cout << "decltype(static_cast<int>(i)) is " << type_name < decltype(static_cast < int > (i)) > () << '\n';
std::cout << "decltype(foo_lref()) is " << type_name < decltype(foo_lref()) > () << '\n';
std::cout << "decltype(foo_rref()) is " << type_name < decltype(foo_rref()) > () << '\n';
std::cout << "decltype(foo_value()) is " << type_name < decltype(foo_value()) > () << '\n';
}