语法问题:`char [5] const&`是什么意思?

问题描述 投票:1回答:2

char [5] const &是什么意思?

恒定左值对5个字符的数组的引用或左值引用5个常量char数组还是左值引用5个字符的const数组?

我正在阅读C ++编程语言的书,正在学习有关char的指针。我找到了以下代码:char s[] = "Gorm";,这使我想起了字符串文字被隐式转换为const char *

所以,我对LHS和RHS不是同一类型感到困惑。

我使用在线编译器和here中的代码来了解编译器如何看待LHS和RHS的类型。然后,我发现LHS被视为char[5],而RHS被视为char[5] const &

我可以解释LHS,但是我不明白什么是“对5个字符的数组的常量左值引用”甚至在将LHS char s[]隐式转换为char* s之后,什么是“常量左值引用指向非const指针的非const char“

不是按定义常量引用左值“它仅是指将其初始化的值]?那么,为什么我们在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';
}
c++ arrays string-literals
2个回答
1
投票

但我不明白什么是“对5个字符的数组的恒定左值引用”

这是用词不当;它是对常量数组的引用,而不是对数组的常量引用。如您所见,引用不能更改,并且const不能应用于它们(因为它们不是对象)。

然后如何分配不同类型的lhs和rhs?

您可以从非常量对象的值创建对常量对象的引用。这是有道理的,因为您正在将可读写的“视图”转换为“只读”。


0
投票

为了消除与“怪异”类型的混淆,了解如何阅读它们很重要。 clockwise/spiral method是前往此处的一种方法。另一种有效的方法是right/left sweep method。尽管这些规则在使用命名类型时效果最好,但仍可以通过简单地从右向左阅读来进行调整。

因此,char[5] const &是对字符大小为5的常量数组的[n值]引用。这听起来像是对字符串文字的准确描述。说数组是常量,这只是意味着内容不能更改,这对于字符串文字是正确的。

作为另一个示例,考虑一个数组:int arr[5]。您可以更改数组的内容,但是arr必须always指向第一个元素,这意味着指针不能更改。声明一个始终指向同一事物的指针可通过以下方法完成:int * const ptr;。我可以更改所指向的值,但不能更改指向的位置。如果声明为const int * const ptrint const * const ptr,则无法更改所指向的值,也不能更改指向的位置。

© www.soinside.com 2019 - 2024. All rights reserved.