2015-07-11 4 views
3

Раздел 9.3.2.1 из C++ стандартных состояний:C++ что такое категория значений * this?

В теле функции члена нестатический (9.3), ключевое слово это prvalue выражение, значение которого является адрес объекта для который вызывается функцией. Тип этого в функции-члене от класса X равен X *. Если функция-член объявлена ​​const, тип это const X *, если функция-член объявлена ​​изменчивой, то тип этого параметра является изменчивым X *, а если объявлена ​​функция-член const volatile, тип это const volatile X *.

Так что если this является prvalue, что значение категории *this? Следующее предполагает, что даже когда объект является rvalue, *this всегда является lvalue. Это верно? Если возможно, обратитесь к стандарту.

struct F; 
struct test 
{ 
    void operator()(F &&) { std::cout << "rvalue operator()" << std::endl; } 
    void operator()(F const &&) { std::cout << "const rvalue operator()" << std::endl; } 
    void operator()(F &) { std::cout << "lvalue operator()" << std::endl; } 
    void operator()(F const &) { std::cout << "const lvalue operator()" << std::endl; } 
}; 

struct F 
{ 
    void operator()() 
    { 
     struct test t; 
     t(*this); 
    } 
}; 

int main() 
{ 
    struct F f; 
    f(); 
    std::move(f)(); 
} 

Выход:

lvalue operator() 
lvalue operator() 
+1

Результат разыменования указателя всегда равен lvalue.В C++ нет указателей xvalue. –

+0

@KerrekSB - это следствие правила «если оно имеет имя»? –

+4

@AmiTavory: Не существует такого правила. Это скорее правило большого пальца, но это не формальная спецификация. Это просто потому, что язык так говорит. По сути, как только вы сможете получить адрес чего-то, у вас есть lvalue. Обратите внимание, что вы не можете использовать адрес rvalues ​​встроенных типов. –

ответ

3

Из [basic.lval]:

именующее (так называемый, исторически, потому что lvalues ​​может появиться на левой части присваивания ) обозначает функцию или объект. [Пример: Если E является выражением типа указателя, то *E является выражением lvalue, относящимся к объекту или функции, к которому относятся E точек. В качестве другого примера, результат вызова функции, возвращаемым типом которой является ссылочным значением lvalue, является lvalue. -end пример]

А из [expr.unary.op]:

Унарный * оператор выполняет косвенность: выражение, к которому она применяется, должны быть указателем на тип объекта или указатель на тип функции, а результатом является lvalue, ссылающийся на объект или функцию , на которое указывает это выражение.

Вывод указателя является значением lvalue. Таким образом, *this - это значение lvalue.

В качестве альтернативы, все, что не является значением lvalue, является значением rvalue. Rvalue является:

Rvalue (так называемый, исторически, потому rvalues ​​может появиться на правой боковой стороне выражения присваивания) является xvalue, временный объект (12.2) или подобъектом их, или значение, которое не связано с с объектом.

И *this, безусловно, ни одна из этих вещей.

+0

Для нормативного текста см. [Expr.unary.op]: _ Унарный * оператор выполняет косвенное выражение: выражение, к которому оно применяется, должно быть указателем на тип объекта или указателем на тип функции, а результатом является значение lvalue, относящееся к объекту или функции , на которое указывает выражение ._ – chris

+0

@ chris Спасибо, добавлено – Barry