char [5] const &是什么意思?
对5个字符数组的常值引用
或对5个常量字符数组的值引用。
还是对5字符的const数组的值引用?
我正在阅读C++编程语言书籍,我正在学习指向字符的指针。我找到了以下代码:char s[] = "Gorm";,它提醒我字符串文本被隐式转换为const char *。
因此,我感到困惑的是,LHS和RHS不是同一类型的。
我使用了这里的在线编译器和代码来了解编译器是如何看待LHS和RHS类型的。然后,我发现LHS被认为是char[5],而RHS被认为是char[5] const &。
我可以解释LHS,但是,我无法理解什么是“对5字符数组的常量lvalue引用”,甚至在LHS char s[]隐式转换为char* s之后,什么是“非const指针到非const char的常值引用”?
按照定义,lvalue引用常量不是“它只指值初始化”吗?那么,为什么我们需要const在&之前
那么,如何分配不同类型的LHS和RHS呢?
下面是代码,我用来获取LHS和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';
}发布于 2019-10-09 15:36:49
char [5] const &不是有效类型。如果您发布的代码给出了这个输出,那么代码就坏了。
下面是检查类型是否有效的方法:
using type = char [5] const &; // error: expected ';' before 'const'字符串的实际类型是const char [N],但在本例中并不重要。
C++有一个特殊的规则,允许用字符串文字初始化字符数组。就这样。
注意,如果将decltype应用于字符串文本,它将为您提供const char (&)[N] (引用char的常量数组)。但这不是文字的实际类型。
这听起来可能令人困惑,但表达式从来没有引用类型。变量有,但没有表达式。请参阅:当解密类型被应用于它们时,哪些表达式会产生引用类型?
如果decltype (当应用于表达式,而不是变量)给出了lvalue引用类型,则表示表达式是lvalue。(rvalue-引用表示xvalue,缺少引用表示prvalue)。
发布于 2019-10-09 10:21:57
但是我不明白什么是“5字符数组的常量lvalue引用”。
这是用词不当;它是对常量数组的引用,而不是对数组的常量引用。正如您所观察到的,引用不能更改,const不能应用于它们(因为它们不是对象)。
那么如何分配不同类型的lhs和rhs呢?
可以从非const对象的值创建对const对象的引用。这是有意义的,因为您正在将读写的“视图”转换为“只读”。
发布于 2019-10-09 15:27:00
为了消除与“怪异”类型的混淆,了解如何阅读它们是很重要的。顺时针/螺旋法是这里的一条路。另一个有效的方法是左右扫描法。虽然当有一个命名类型时,这些规则工作得最好,但它仍然可以通过从右到左的简单阅读来调整。
因此,char[5] const &是对大小为5的常量数组的l值引用.这听起来像是对字符串文字的准确描述。如果说数组是常量,那就意味着内容不能改变,这对于字符串文本来说是正确的。
作为另一个例子,考虑一个数组:int arr[5]。您可以更改数组的内容,但arr必须始终指向第一个元素,这意味着指针不能更改。声明始终指向同一事物的指针是用:int * const ptr;完成的。我可以改变我所指向的东西的价值,但我不能改变我所指向的位置。如果声明为const int * const ptr或int const * const ptr,则不能更改所指向的值,也不能更改所指向的位置。
https://stackoverflow.com/questions/58301755
复制相似问题