Квалифицированные идентификаторы, это lvalues ​​или prvalues?

Я пытался проверить это утверждение (мой акцент) в параграфе §5.1.1/8 (стр. 87) стандарта C++11

Спецификатор вложенного имени, который обозначает класс, за которым необязательно следует ключевое слово template (14.2), а затем следует имя члена этого класса (9.2) или одного из его базовых классов (пункт 10), квалифицированный-ID; 3.4.3.1 описывает поиск имен для членов класса, которые появляются в квалифицированных идентификаторах. Результатом является член. Тип результата - это тип члена. Результатом является lvalue, если член является статической функцией-членом или элементом данных, а в противном случае - prvalue.

со следующим фрагментом:

#include <iostream>

namespace N {
    class A {
    public:
        int i;
        void f();
    };
}

int main()
{
    std::cout << &N::A::f << '\n';
    std::cout << &N::A::i << '\n';
}

clang а также gcc скомпилируйте этот код и VS2013 требует определения функции-члена f,

Все три из них печатают

1
1

но я понятия не имею, откуда эти цифры.

живой пример

Согласно пункту, выделенному выше выражений N::A::f это prvalue, как f не является статической функцией-членом. Тем не менее, я смог взять его адрес в коде.

В то же время в §5.3.1/3 говорится (выделено мое):

Результатом унарного оператора & является указатель на его операнд. Операндом должно быть lvalue или квалифицированный идентификатор. Если операндом является квалифицированный идентификатор, называющий нестатический член m некоторого класса C с типом T, результат имеет тип "указатель на член класса C типа T" и является предварительным значением, обозначающим C::m.

что создает впечатление, что ни N::A::f ни N::A::i являются lvalues, поскольку они являются квалифицированными идентификаторами.

1 ответ

Решение

но я понятия не имею, откуда эти цифры.

Указатели на участников не являются указателями. нет operator<< может выводить их исходное значение, лучшее и единственное совпадение - это то, которое выводит bool ценности. Таким образом, они преобразуются в bool (что, очевидно, дает true) и вывод 1, Попробуй вставить std::boolalpha и проверьте вывод еще раз.

Тем не менее, я смог взять его адрес в коде.

Как это вас удивляет? Вы процитировали ту часть, которая позволяет и объясняет эту точную конструкцию. В нем четко указано, что взятие адреса квалифицированного идентификатора, в котором указан нестатический элемент, обозначает этот элемент.

квалифицированные идентификаторы- это не только значения или значения. Это полностью зависит от контекста. Если они обозначают нестатические члены извне этого класса членов или любого его подкласса, они должны быть prvalues, поскольку они не обозначают какой-либо конкретный объект, а скорее значение (или информацию, другими словами - тип и смещение)).

Другие вопросы по тегам