Что за выражение (1, S::x)?

76
07 февраля 2022, 14:20

Что за выражение?

(1, S::x)

Взято из след. кода:

struct S {
    static const int x = 0; // static data member
    // a definition outside of class is required if it is odr-used
};
const int& f(const int& r);
int n = b ? (1, S::x) // S::x is not odr-used here
          : f(S::x);  // S::x is odr-used here: a definition is required
Answer 1

Пытаюсь навести порядок. Прежде всего, это код из C++ standard: http://eel.is/c++draft/basic.def.odr и cpp-reference: https://en.cppreference.com/w/cpp/language/definition Код не имеет никакого практического значения, кроме демонстрации данной концепции C++. Фрагменты стандарта с моими вставками:

A non-overloaded function const int &f(const int &r) whose name appears as a potentially-evaluated expression f(S::x), if selected by overload resolution when referred to from a potentially-evaluated expression, is odr-used Функция вызывается или ее адрес используется.

The set of potential results of an expression e is defined as follows: ... If e is a comma expression (1, S::x), the set contains the potential results of the right operand S::x. ...

Итак: (1, S::x) S::x используется для оценки выражения (1, S::x). Оценка прозводится во время компиляции, при этом не выполняется ни одно из условий value is read or written, its address is taken, поэтому выражение компилируется (S::x is not ODR-used).

С другой стороны, в выражении f(S::x) функция f is odr-used, (см. параграф non-overloaded function), поэтому требуется ее вызвать, результат - linker error, function f is undefined.

И еще: https://en.cppreference.com/w/cpp/language/operator_other Other operators, Built-in comma operator. Эта часть самая простая:

E1 ,E2 - E1 is evaluated, its result is discarded,expression result is E2

Answer 2

(1,S::x) - просто использован оператор "запятая", причем первая его часть - 1 - ничего не выполняет.

Так что можно оставить только обращение к статическому члену класса (структуры) S::x.

Скобка нужна, потому что приоритет оператора , самый низкий, ниже, чем у тернарного оператора.

Зачем это извращение и почему не написать просто

int n = b ? S::x : f(S::x);

не вижу. Никаких тонкостей, связанных со ссылочностью, мне лично тоже не видно. Возможно, ошибаюсь - но тогда это какая-то слишком тонкая тонкость :)

"По-моему, так" (с) Пух

READ ALSO
Указатель на const в MSVC и GCC

Указатель на const в MSVC и GCC

По какой причине данный код в MSVC работает иначе, нежели в gcc:

87
Как наложить одно изображение на другое в opencv 3?

Как наложить одно изображение на другое в opencv 3?

Имеются два изображения, как наложить одно изображение на другое в opencv 3? C++

94
Как удалить элементы из std::list<std::pair<>>;

Как удалить элементы из std::list<std::pair<>>;

Помогите удалить элементы из std::list>;

89
Python + MySQL Не происходит заполнение БД

Python + MySQL Не происходит заполнение БД

Попытался связать бота в телеграм с базой данных, но возникла проблема с её заполнениемИнформация в БД не обновляется, скорее всего это связано...

104