Можем ли мы привести не-класс prvalue к xvalue? - PullRequest
5 голосов
/ 03 мая 2019

Рассмотрим этот пример из 7.6.1.10, параграф 3 [expr.const.cast] ( N4810 ):

typedef int *A[3]; // array of 3 pointer to int
typedef const int *const CA[3]; // array of 3 const pointer to const int
...
A &&r2 = const_cast<A&&>(CA{}); // OK

Итак, стандарт гласит это законный код, но

  • ни один из g++-7 или clang-6 не компилируется нормально.

  • На самом деле, это const_cast связанных * комментариев из llvm состояний:

    ....
    
    if (isa<RValueReferenceType>(DestTypeTmp) && SrcExpr.get()->isRValue()) {
        if (!SrcType->isRecordType()) {
            // Cannot const_cast non-class prvalue to rvalue reference type. But if
            // this is C-style, static_cast can do this.
            msg = diag::err_bad_cxx_cast_rvalue;
            return TC_NotApplicable;
        }
    
        // Materialize the class prvalue so that the const_cast can bind a
        // reference to it.
        NeedToMaterializeTemporary = true;
    }
    
    ...
    

    Это в основном говорит о том, что мы не можем материализовать (= приведение) не-класс prvalue до xvalue .

  • Кроме того, тот же абзац, из которого происходит вышеприведенный пример, гласит:

    Для двух похожих типов T1 и T2 значение типа T1 может быть явно преобразовано в тип T2 с помощью const_cast.Результат const_cast относится к исходной сущности .

    Сравните это с одним сразу после него (7.6.1.10, параграф 4 [expr.const.cast]):

    Для двух типов объектов T1 и T2, если указатель на T1 можно явно преобразовать в тип «указатель на T2» с помощью const_cast,затем можно также выполнить следующие преобразования:

    • и lvalue типа T1 можно явно преобразовать в lvalue типа T2 с помощьюприведение const_cast<T2&>;
    • a glvalue типа T1 может быть явно преобразовано в xvalue типа T2 с использованием приведения const_cast<T2&&>
    • , если T1 является типом класса , prvalue типа T1 может быть явно преобразовано в xvalue типаT2 с использованием приведения const_cast<T2&&>.

    Результат ссылки const_cast ссылается на исходный объект, если операнд является glvalue, а - на результат применения временного преобразования материализации в противном случае..

    Этот контраст, по-видимому, намекает на то, что приведение от некласса prvalue к xvalue не пострадает временное преобразование материализации, что выглядит странно для меня.

Тогда каков смысл приведенного выше примера?

...