Re[18]: Зачем плюс?
От: rg45 СССР  
Дата: 28.11.18 11:27
Оценка: +2
Здравствуйте, N. I., Вы писали:

NI>По данному же топику видно, что товарищ пытается делать какие-то умозаключения, не вникая в смысл основных терминов и жонглируя ими как попало. До тех пор, пока он не изменит свой подход, объяснять ему что-либо, скорее всего, бесполезно.


А, по-моему, у него нет намерений с вами спорить. У вас нет необходимости его переубеждать, просто помогите разобраться, он будет благодарен. И не только он.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[18]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 13:55
Оценка:
Здравствуйте, N. I., Вы писали:

BFE>>В соответствии с этим принципом, что из нижепреведённого сообщения об ошибке является названием типа?:

  Скрытый текст
BFE>>

NI>cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'

BFE>>Вот это тип:
BFE>>

NI>non-const lvalue reference of type 'int&'

BFE>>или нет?
BFE>>А это:
BFE>>

NI>rvalue of type 'int'

BFE>>?


NI>Разве в самом сообщении об ошибке недостаточно ясно указано, что там относится к типам?

Недостаточно.
Почему, например, non-const lvalue reference of type 'int&', а не non-const lvalue reference of type 'int' ?

NI>
prog.cc: In function 'int main()':
NI>prog.cc:6:29: error: cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'
NI>    6 |     int &lvalue_ref = rvalue();
NI>      |                       ~~~~~~^~
NI>prog.cc:7:30: error: cannot bind rvalue reference of type 'int&&' to lvalue of type 'int'
NI>    7 |     int &&rvalue_ref = lvalue();
NI>      |                        ~~~~~~^~

NI>По-моему, яснее уже некуда...

Ну я не знаю. В стандарте написано по другому:

typedef int& A;
const A aref = 3;
// ill-formed; lvalue reference to non-const initialized with rvalue
The type of aref is “lvalue reference to int”, not “lvalue reference to const int”.

На мой взгляд, то , что взято в кавычки: “lvalue reference to int” является названием типа. Поэтому, на мой взгляд, ваша интерпретация типов не верна. Я ошибаюсь? Где?

  Скрытый текст
9.2.3.2/1 References
In a declaration T D where D has either of the forms
& attribute-specifier-seq opt D1
&& attribute-specifier-seq opt D1
and the type of the identifier in the declaration T D1 is “derived-declarator-type-list T”, then the type of the
identifier of D is “derived-declarator-type-list reference to T”. The optional attribute-specifier-seq appertains
to the reference type. Cv-qualified references are ill-formed except when the cv-qualifiers are introduced
through the use of a typedef-name (9.1.3, 12.1) or decltype-specifier (9.1.7.2), in which case the cv-qualifiers
are ignored. [Example:
typedef int& A;
const A aref = 3;
// ill-formed; lvalue reference to non-const initialized with rvalue
The type of aref is “lvalue reference to int”, not “lvalue reference to const int”. — end example] [Note:
A reference can be thought of as a name of an object. — end note] A declarator that specifies the type
“reference to cv void” is ill-formed.
2 A reference type that is declared using & is called an lvalue reference, and a reference type that is declared
using && is called an rvalue reference. Lvalue references and rvalue references are distinct types. Except
where explicitly noted, they are semantically equivalent and commonly referred to as references.
И каждый день — без права на ошибку...
Re[18]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 14:40
Оценка:
Здравствуйте, N. I., Вы писали:

σ>>>Для инициализации ссылок важен не только тип, но и value category.

BFE>>Т.е. вы хотите сказать, что два объекта одного и того же типа не являются взаимозаменяемыми?
NI>Сказанное выше относилось к выражениям, а не объектам.
А вопрос был про объекты, а не выражения.

BFE>>Поясню.

BFE>>Допустим у меня есть два объекта a1 и a2 типа int. Вы утверждаете, что нельзя один объект, скажем a1, заменить другим объектом — a2, не смотря на то, что эти два объекта одинакового типа. Вам не кажется это странным? Т.е. теперь, по вашему мнению, поведение объекта не определяется его типом?

NI>Для начала тебе надо уяснить, что такое "объект", что такое "выражение", и чем одно отличается от другого. Без понимания этих терминов дальше ты не продвинешься.

Объект — это то, что занимаете некоторую память, имеет время жизни и тип.
Выражение — это некая последовательность символов составленная по определённым правилам служащая для манипуляций и доступа к объектам.
Но вы забыли ещё упомянуть третью сущность — ссылку. Ссылка не является не объектом и не является выражением. Она может рассматриваться как нечто ссылающиеся на объект, например как имя объекта.

NI>В общем случае возможность инициализации ссылки неким инициализатором зависит от трёх характеристик выражения, используемого в качестве данного инициализатора: тип, value category и принадлежность к bit-field. Ни value category, ни принадлежность к bit-field не являются частью типа — это отдельные характеристики.

Отдельные характеристики чего?

Если value category не является частью типа, то почему в стандарте написано так:

A reference type that is declared using & is called an lvalue reference, and a reference type that is declared using && is called an rvalue reference.

Указанные 'lvalue' и 'rvalue' не являются частью названия типа? Откуда это следует? Или lvalue reference — это не тип, а просто название ссылки?
Вот, например, вы пишите:
NI>Например, lvalue reference to int можно инициализировать посредством non-bit-field lvalue of type int, но нельзя инициализировать посредством rvalue of type int или bit-field of type int:
"lvalue reference to int" — что это? Тип? Название? Категория?
И каждый день — без права на ошибку...
Re[19]: Зачем плюс?
От: N. I.  
Дата: 28.11.18 14:42
Оценка:
B0FEE664:

NI>>Разве в самом сообщении об ошибке недостаточно ясно указано, что там относится к типам?

BFE>Недостаточно.
BFE>Почему, например, non-const lvalue reference of type 'int&', а не non-const lvalue reference of type 'int' ?

В данном случае речь идёт о типе ссылки как самостоятельной сущности, а не типе выражения, которое можно получить, используя имя lvalue_ref в качестве id-expression. Как самостоятельная сущность, ссылка имеет ссылочный тип.

BFE>Ну я не знаю. В стандарте написано по другому:

BFE>

BFE>typedef int& A;
BFE>const A aref = 3;
BFE>// ill-formed; lvalue reference to non-const initialized with rvalue
BFE>The type of aref is “lvalue reference to int”, not “lvalue reference to const int”.

BFE>На мой взгляд, то , что взято в кавычки: “lvalue reference to int” является названием типа.

“lvalue reference to int” и “int &” обозначают один и тот же тип. Первое — это название типа прописью, а второе — запись того же типа по правилам синтаксиса языка C++. (неужели ещё и это надо объяснять? )

BFE>Поэтому, на мой взгляд, ваша интерпретация типов не верна. Я ошибаюсь? Где?


Я не вижу какой-либо причинно-следственной связи в твоём рассуждении.
Re[19]: Зачем плюс?
От: rg45 СССР  
Дата: 28.11.18 15:03
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>Ну я не знаю. В стандарте написано по другому:

BFE>

BFE>typedef int& A;
BFE>const A aref = 3;
BFE>// ill-formed; lvalue reference to non-const initialized with rvalue
BFE>The type of aref is “lvalue reference to int”, not “lvalue reference to const int”.

BFE>На мой взгляд, то , что взято в кавычки: “lvalue reference to int” является названием типа. Поэтому, на мой взгляд, ваша интерпретация типов не верна. Я ошибаюсь? Где?

Я попробую дать объяснение, как я это понимаю, да простят мне гуру вероятные неточности.

Важно четко понимать смысл таких сущностей как "тип", "выражение" и "объект" и их взаимоотношения. Согласно 6.9:

Types describe objects (4.5), references (11.3.2), or functions (11.3.5).


Заметьте, о выражениях пока ни слова.

Идем дальше: "6.10 Lvalued and rvalues". "Expressions are categorized according to the taxonomy." И далее идет хорошо известная всем картинка:



Из которой понятно, что все эти страшные слова "glvalue", "prvalue", "xvalue", etc — это категории выражений. и чтобы установить мостик между понятиями "тип" и "выражение" нам нужно найти связь между выражениями и теми сущностями, которые описывают типы (objects, references functions). И связь эта находится тут же, прямо под картинкой:

(1.1) — A glvalue is an expression whose evaluation determines the identity of an object, bit-field, or function.
(1.2) — A prvalue is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
(1.3) — An xvalue is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime)...
(1.4) — An lvalue is a glvalue that is not an xvalue.
(1.5) — An rvalue is a prvalue or an xvalue.


Таким образом, когда мы говорим о типе выражения мы всегда подразумеваем тип объекта или ссылки, которые сопоставлены данному выражению, прямо или косвенно, не забывая при этом о категории самого выражения.

Возвращаясь к примеру:

typedef int& A;
const A aref = 3;
// ill-formed; lvalue reference to non-const initialized with rvalue
The type of aref is “lvalue reference to int”, not “lvalue reference to const int”.


Мы говорим, что здесь присутствуют: неконстантная lvalue ссылка aref, имеющая тип int&. И prvalue выражение '3', вычисление которого инициализирует объект типа int. Или проще — prvalue типа int — я бы так сказал и не парился. Ну и понятно, что prvalue не может быть связано с неконстантной lvalue ссылкой, поэтому компилятор ругается.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 28.11.2018 15:12 rg45 . Предыдущая версия . Еще …
Отредактировано 28.11.2018 15:08 rg45 . Предыдущая версия .
Отредактировано 28.11.2018 15:05 rg45 . Предыдущая версия .
Re[12]: Зачем плюс?
От: σ  
Дата: 28.11.18 15:13
Оценка:
Тут такой вопрос.
Допустим, есть указатель на int, реально указывающий на объект типа int.
Мы его кастуем к указателю на unsigned int, разыменовываем и читаем значение (lvalue-to-rvalue conversion).

Тип prvalue понятно — unsigned int. А тип value какой?
Из более-менее релевантного что нашёл это одна невнятная фраза
> For other objects, the interpretation of the values found therein is determined by the type of the expressions ([expr.compound]) used to access them.
Re[20]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 15:13
Оценка:
Здравствуйте, N. I., Вы писали:

NI>“lvalue reference to int” и “int &” обозначают один и тот же тип. Первое — это название типа прописью, а второе — запись того же типа по правилам синтаксиса языка C++. (неужели ещё и это надо объяснять? )


Ок. Хорошо. “lvalue reference to int” — обозначает тип ссылки. Замечательно. Тогда в выражении:
int &lvalue_ref = rvalue();

lvalue_ref — это ссылка типа “lvalue reference to int”.
Тогда смотрим на вторую часть сообщения:

cannot bind non-const lvalue reference of type 'int&' to an rvalue of type 'int'

Вы меня уверяете, что rvalue — это тип выражения. Так? Если так, то вы хотите сказать, что ссылка привязывается (bind) к выражению, а не к объекту?
И каждый день — без права на ошибку...
Re[19]: Зачем плюс?
От: N. I.  
Дата: 28.11.18 15:14
Оценка:
B0FEE664:

σ>>>>Для инициализации ссылок важен не только тип, но и value category.

BFE>>>Т.е. вы хотите сказать, что два объекта одного и того же типа не являются взаимозаменяемыми?
NI>>Сказанное выше относилось к выражениям, а не объектам.
BFE>А вопрос был про объекты, а не выражения.

Если речь про этот вопрос

Если n и +A::TIMEOUT имеют одинаковый тип, то почему мы имеем разницу в поведении?


то в данном случае разница имеет место быть из-за различия value category выражений n и +A::TIMEOUT.

NI>>В общем случае возможность инициализации ссылки неким инициализатором зависит от трёх характеристик выражения, используемого в качестве данного инициализатора: тип, value category и принадлежность к bit-field. Ни value category, ни принадлежность к bit-field не являются частью типа — это отдельные характеристики.

BFE>Отдельные характеристики чего?

Выражения (внимательно читай предшествующее предложение)

BFE>Указанные 'lvalue' и 'rvalue' не являются частью названия типа?


"lvalue reference" и "lvalue" — это разные понятия. Первое — это разновидность ссылок или ссылочный тип (в зависимости от контекста использования), второе — разновидность выражений.

BFE>Или lvalue reference — это не тип, а просто название ссылки?


В зависимости от контекста употребления, "lvalue reference" может означать как ссылочный тип (если речь идёт о типе), так и ссылку как сущность ссылочного типа.

BFE>Вот, например, вы пишите:

NI>>Например, lvalue reference to int можно инициализировать посредством non-bit-field lvalue of type int, но нельзя инициализировать посредством rvalue of type int или bit-field of type int:
BFE>"lvalue reference to int" — что это? Тип? Название? Категория?

В данном контексте это сущность, имеющая ссылочный тип. Как, по-твоему, можно инициализировать тип, название или категорию? Включи уже мозг, наконец...
Отредактировано 28.11.2018 19:08 N. I. . Предыдущая версия .
Re[21]: Зачем плюс?
От: N. I.  
Дата: 28.11.18 15:22
Оценка:
B0FEE664:

BFE>Вы меня уверяете, что rvalue — это тип выражения. Так?


Ткни пальцем, где я такое говорил?

BFE>Если так, то вы хотите сказать, что ссылка привязывается (bind) к выражению, а не к объекту?


Binding to an expression — это неформальная фигура речи, обозначающая привязку к объекту или функции, что является результатом данного expression.
Re[20]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 15:40
Оценка:
Здравствуйте, rg45, Вы писали:

R>Мы говорим, что здесь присутствуют: неконстантная lvalue ссылка aref, имеющая тип int&. И prvalue выражение '3', вычисление которого инициализирует объект типа int. Или проще — prvalue типа int — я бы так сказал и не парился. Ну и понятно, что prvalue не может быть связано с неконстантной lvalue ссылкой, поэтому компилятор ругается.


Я выделил мне не понятное. До этой темы я считал, что вычисление prvalue в данном случае должно давать временный объект типа int&&, т.е. rvalue reference, которую к lvalue reference привязать нельзя (но можно к const lvalue reference), в отличии от объекта типа int, который легко привязывается к lvalue reference:
int& r2 = *(new int);

И каждый день — без права на ошибку...
Re[21]: Зачем плюс?
От: σ  
Дата: 28.11.18 15:44
Оценка:
BFE>объект типа int&&

У объекта не может быть ссылочного типа в принципе.
Re[21]: Зачем плюс?
От: rg45 СССР  
Дата: 28.11.18 15:47
Оценка:
Здравствуйте, B0FEE664, Вы писали:

R>>Мы говорим, что здесь присутствуют: неконстантная lvalue ссылка aref, имеющая тип int&. И prvalue выражение '3', вычисление которого инициализирует объект типа int. Или проще — prvalue типа int — я бы так сказал и не парился. Ну и понятно, что prvalue не может быть связано с неконстантной lvalue ссылкой, поэтому компилятор ругается.


BFE>Я выделил мне не понятное. До этой темы я считал, что вычисление prvalue в данном случае должно давать временный объект типа int&&, т.е. rvalue reference, которую к lvalue reference привязать нельзя (но можно к const lvalue reference)...


Времменный объект — да, только типа int а не int&&. Рассмотрим другой пример:

int&& foo();
// . . .
int&& a = 42;
int&& b = foo();


В обоих слуючаях — привязка к rvalue ссылкам. Только в первом случае prvalue и временный объект типа int, а во втором — xvalue, без всякого временного объекта (glvalue that denotes an object whose resources can be reused).
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 28.11.2018 15:51 rg45 . Предыдущая версия . Еще …
Отредактировано 28.11.2018 15:48 rg45 . Предыдущая версия .
Re[22]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 15:48
Оценка:
Здравствуйте, N. I., Вы писали:

BFE>>Вы меня уверяете, что rvalue — это тип выражения. Так?

NI>Ткни пальцем, где я такое говорил?
σ писал, что rvalue — это класс выражений. Он прав, потому что в стандарте так и написано.

BFE>>Если так, то вы хотите сказать, что ссылка привязывается (bind) к выражению, а не к объекту?

NI>Binding to an expression — это неформальная фигура речи, обозначающая привязку к объекту или функции, что является результатом данного expression.

Ну, тогда я повторю свой вопрос: какой тип у объекта полученного в результате вычисления rvalue?
И каждый день — без права на ошибку...
Re[22]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 15:55
Оценка:
Здравствуйте, σ, Вы писали:

BFE>>объект типа int&&

σ>У объекта не может быть ссылочного типа в принципе.
Какой тип у результата выражения n + 1, если n типа int?
И каждый день — без права на ошибку...
Re[23]: Зачем плюс?
От: σ  
Дата: 28.11.18 15:58
Оценка:
BFE>>>объект типа int&&
σ>>У объекта не может быть ссылочного типа в принципе.
BFE>Какой тип у результата выражения n + 1, если n типа int?
int?
Re[23]: Зачем плюс?
От: N. I.  
Дата: 28.11.18 16:10
Оценка:
B0FEE664:

BFE>Здравствуйте, N. I., Вы писали:


BFE>>>Вы меня уверяете, что rvalue — это тип выражения. Так?

NI>>Ткни пальцем, где я такое говорил?
BFE>σ писал, что rvalue — это класс выражений.

Под классом выражений он явно не имел в виду тип выражения.

BFE>>>Если так, то вы хотите сказать, что ссылка привязывается (bind) к выражению, а не к объекту?

NI>>Binding to an expression — это неформальная фигура речи, обозначающая привязку к объекту или функции, что является результатом данного expression.

BFE>Ну, тогда я повторю свой вопрос: какой тип у объекта полученного в результате вычисления rvalue?


Зависит от rvalue и версии стандарта. В случае C++11/14 у prvalue скалярного типа (например, int) результирующего объекта вообще нет. Например, литерал 42 вычисляется в pure value, для которого никаких объектов не создаётся. Если таким prvalue инициализируется ссылка, то временный объект создаётся в контексте её инициализации (самому же prvalue при этом никаких объектов не сопоставляется).

В случае C++17 prvalue скалярного типа может иметь результирующий объект, а может и не иметь, в зависимости от контекста. У prvalue типа void результирующего объекта не может в принципе.
Отредактировано 28.11.2018 16:34 N. I. . Предыдущая версия . Еще …
Отредактировано 28.11.2018 16:32 N. I. . Предыдущая версия .
Отредактировано 28.11.2018 16:13 N. I. . Предыдущая версия .
Re[24]: Зачем плюс?
От: B0FEE664  
Дата: 28.11.18 16:13
Оценка:
Здравствуйте, σ, Вы писали:

BFE>>>>объект типа int&&

σ>>>У объекта не может быть ссылочного типа в принципе.
BFE>>Какой тип у результата выражения n + 1, если n типа int?
σ>int?

если считать, что int, то я повторю свой пример:
void foo(int&& n){}

int main()
{
    int n = 3;
    foo(n);     // мы точно знаем, что у n тип int. ошибка компиляции.
    foo(1 + n); // ошибки компиляции нет, значит результат вычисления (1 + n)  - не int.
}

Я полагаю, что результат вычисления имеет тип int&&. Почему это не так?
И каждый день — без права на ошибку...
Re[23]: Зачем плюс?
От: rg45 СССР  
Дата: 28.11.18 16:16
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>>>объект типа int&&

σ>>У объекта не может быть ссылочного типа в принципе.
BFE>Какой тип у результата выражения n + 1, если n типа int?

int, конечно же, не int&&. Рассмотри для сравнения два выражения: n + 1, и, например, std::move(n). Оба выражения — rvalue. Но только первое — это prvalue, которое может быть преобразовано во временный объект, а второе — xvalue, которое уже "denotes an object" и создание временного объекта не требуется.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[25]: Зачем плюс?
От: σ  
Дата: 28.11.18 16:19
Оценка:
BFE>
void foo(int&& n){}

int main()
{
    int n = 3;
    foo(1 + n); // ошибки компиляции нет, значит результат вычисления (1 + n)  - не int.
}

BFE>Я полагаю, что результат вычисления имеет тип int&&.

А если бы было
void foo(const int& n){}
ты бы полагал что результат вычисления имеет тип const int& ?
Re[25]: Зачем плюс?
От: rg45 СССР  
Дата: 28.11.18 16:21
Оценка:
Здравствуйте, B0FEE664, Вы писали:

BFE>если считать, что int, то я повторю свой пример:

BFE>
BFE>void foo(int&& n){}

BFE>int main()
BFE>{
BFE>    int n = 3;
BFE>    foo(n);     // мы точно знаем, что у n тип int. ошибка компиляции.
BFE>    foo(1 + n); // ошибки компиляции нет, значит результат вычисления (1 + n)  - не int.
BFE>}
BFE>

BFE>Я полагаю, что результат вычисления имеет тип int&&. Почему это не так?

Потому, что выражение n — это lvalue типа int, (whose evaluation determines the identity of an object), которое не может быть приязано к rvalue ссылке.
--
Не можешь достичь желаемого — пожелай достигнутого.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.