Войти
ФлеймФорумПрограммирование

[C++] Как такая фигня с дизайном языка получилась?

Страницы: 1 2 310 11 Следующая »
#0
(Правка: 4:04) 3:25, 2 июля 2019

Всем привет.

Есть такой код(идею нашёл тут):

#include <bits/stdc++.h>
#include <typeinfo>
using namespace std;
void show(string r,string t){printf("ref='%s'; tmp='%s';\n",r.c_str(),t.c_str());}
template<class TYPE>
void foo(TYPE&ref,bool a,bool b){
  TYPE tmp=ref; // <---- тут беда, если foo звать как foo<string&>(...);
  if(a)tmp="a";
  if(b)ref="b";
  show(ref,tmp);
}
int main(){
  #define F(CODE){string s="s";printf("%s // ",#CODE);CODE;}
  F(  foo<string&>(s,1,0);  );
  F(  foo<string >(s,1,0);  );
  F(  foo<string&>(s,0,1);  );
  F(  foo<string >(s,0,1);  );
  F(  foo<string&>(s,1,1);  );
  F(  foo<string >(s,1,1);  );
  #undef F
}
stdout(из https://ideone.com/u6FGqb):
foo<string&>(s,1,0); // ref='a'; tmp='a';
foo<string >(s,1,0); // ref='s'; tmp='a';
foo<string&>(s,0,1); // ref='b'; tmp='b';
foo<string >(s,0,1); // ref='b'; tmp='s';
foo<string&>(s,1,1); // ref='b'; tmp='b';
foo<string >(s,1,1); // ref='b'; tmp='a';
Это норм?
Если нет, то:
  Как такая фигня с дизайном языка получилась?
  Как такой фигни надо было избежать?
как бы эту проблему/тему назвать?
ну и ещё не понятно, что делать если набегут с ответом типа: "... всегда используй 'TYPE&&ref' ..."


#1
4:04, 2 июля 2019

Если tmp это string&, то она лишь псевдоним (ссылка) на ref и её изменение приведёт к изменению ref. Это что ли смутило?

#2
(Правка: 4:19) 4:08, 2 июля 2019

=A=L=X=
> Если tmp это string&, то она лишь псевдоним (ссылка) на ref и её изменение
> приведёт к изменению ref. Это что ли смутило?
это только следствие ошибки, примерно такой:
"ref" внутри функции ожидается как ссылка, а "TYPE" как не ссылка, но он оказываться может быть ссылкой и при этом вызов функции не рожает ошибку компиляции.

понятно, что можно её static_assert`ом родить, но это уже костыль.

немного спасает то что шаблоны пишутся редко и не нубами, но всё равно на code-review такое запросто можно пропустить/не_заметить.

#3
4:21, 2 июля 2019

Adler
> а "TYPE" как не ссылка, но он оказываться может быть ссылкой и при этом вызов
> функции не рожает ошибку компиляции.

В плюсах тип вида TYPE && который тут получается в таком случае - это ссылка с особыми семантиками которая реализует perfect forwarding, подробнее можно прочитать тут: https://habr.com/ru/post/242639/ я же всё время забывают детали.
Но это ссылка, а потому не очень понятно что именно тебе не нравится.

#4
4:27, 2 июля 2019

А, вот конкретика из ссылки выше:

Не позволяйте двойному амперсанду обмануть Вас – t здесь не является rvalue-ссылкой [2]. При появлении в данной ситуации (когда необходим особый вывод типа), T&& принимает особое значение – когда func инстанцируется, T изменяется в зависимости от переданного типа. Если была передана lvalue типа U, то Т становится U&. Если же U это rvalue, то Т становится просто U. Пример:
Т.к. у тебя ref это не r-value, то вторая часть правила по идее не должна срабатывать и должна быть просто ссылка.

#5
(Правка: 4:46) 4:33, 2 июля 2019

=A=L=X=
> В плюсах тип вида TYPE && который тут получается в таком случае
не вижу "&&": https://ideone.com/VDPZnt

void foo(TYPE &, bool, bool) [TYPE = std::__cxx11::basic_string<char> &]
#6
(Правка: 4:37) 4:36, 2 июля 2019

Adler
> не вижу "&&"

А его и не будет - см. выше.
Я всё-таки так и не понял что именно тебе не нравится - код на первый взгляд работает как и должен (даже без заморочек с универсальными ссылками). А как хочется то?

#7
(Правка: 6:00) 5:59, 2 июля 2019

команду fpc ругают, "треклятыми ретроградами" за то что они не тащат произвольные фичи в язык. А всё, чтобы не было паскалепроблем.

Пишите в Паскале!

#8
6:27, 2 июля 2019

skalogryz
Один фиг, все компиляторы-то все равно как бы диверсанты делали:
То GC воткнут
То eval забудут
То препроцессор говно
То шаблонов нет
То шаблоны есть, да скобки говно.
То синтаксис говно.
То IDE отстой.
То компилится долго.
...

:)

#9
9:17, 2 июля 2019

=A=L=X=
> TYPE && который тут получается в таком случае
&& получится, если ты напишешь &&

#10
9:26, 2 июля 2019

Adler
> Один фиг, все компиляторы-то все равно как бы диверсанты делали:
> То GC воткнут
> То eval забудут
> То препроцессор говно
> То шаблонов нет
> То шаблоны есть, да скобки говно.
> То синтаксис говно.
> То IDE отстой.
> То компилится долго.
плохому танцору

#11
9:38, 2 июля 2019

Всё нормально.
Подумалося: а если бы perfect forward изобрели раньше и сделали бы по-умолчательным способом передачи аргументов?

#12
10:22, 2 июля 2019

C++ ДОЛЖЕН БЫТЬ ЗАБЫТ

#13
10:26, 2 июля 2019

Джек Аллигатор
А какая замена?

#14
10:27, 2 июля 2019

Vlad2001_MFS
rust-logo-blk | [C++] Как такая фигня с дизайном языка получилась?

Страницы: 1 2 310 11 Следующая »
ФлеймФорумПрограммирование