
Oleg
18.09.2016
19:43:39
попробуй сначала предложить сам такие ситуации

Макс
18.09.2016
20:25:40
ой
Сорри, не сюда

Dmitry
20.09.2016
13:17:25
А в чем разница между functionAttributes
https://dlang.org/phobos/std_traits.html#functionAttributes
И getAttributes которая вызывается через __traits __traits(getAttributes, Person.name)

Google

Dmitry
20.09.2016
13:18:52
один для функции, другой для класса чтоли?

Eto
20.09.2016
13:20:45
functionAttributes использует внутри __traits(getFunctionAttributes.

Dmitry
20.09.2016
13:26:43
второе это именно языковая фича, а первое библиотечная так?
Просто я не пойму почему в std.traits есть: SetFunctionAttributes но нет GetFunctionAttributes
где логика?

Eto
20.09.2016
13:33:49
Разве funtionAttributes не выполняет функционал второго?

Dmitry
20.09.2016
13:38:29
это дублирующийся функционал получается?

Anatoly
20.09.2016
13:39:14
ну некоторым кажется, что дёргать __traits в коде конечного погромца - как-то не очень

Grigirii
20.09.2016
13:39:26
functionAttributes = атрибуты функции, такие как nothrow, а attributes - UDA

Anatoly
20.09.2016
13:39:40
хм

Dmitry
20.09.2016
13:39:53
а...

Anatoly
20.09.2016
13:40:04
я думал мы про getFunctionAttributes

Dmitry
20.09.2016
13:41:20
так, а в чем разница тогда: getUDAs и GetFunctionAttributes второе же тоже про UDA

Google

Dmitry
20.09.2016
13:51:22
а могу я сделать так:
A a = new A();
foreach (x; Fields(a))
{
writeln(x);
}
еслb что я про https://dlang.org/phobos/std_traits.html#Fields

Grigirii
20.09.2016
13:52:55
на самом последнем dmd да

Dmitry
20.09.2016
13:53:25
` Error: template std.traits.Fields cannot deduce function from argument types !()(A), candidates are:
C:\D\dmd2\windows\bin\..\..\src\phobos\std\traits.d(2174,1): std.traits.Fields(T)`

Grigirii
20.09.2016
13:54:07
значит A, а не a. Ему тип нужен

Dmitry
20.09.2016
13:54:36
а самый последний это какой? у меня v2.071.1

Grigirii
20.09.2016
13:55:28
2.071.2, в нём баг с этим foreach фиксили
до этого он работал только в рантайме
сегодня зарелизили

Dmitry
20.09.2016
13:56:03
foreach (x; Fields(A))
Error: cannot pass type A as a function argument
это может быть следиствием бага? Щас обновлюсь

Grigirii
20.09.2016
13:56:37
нет, надо Fields!A
это же шаблонный аргумент

Dmitry
20.09.2016
13:57:30
Все шаблоны передаются через восклицательный так?

Grigirii
20.09.2016
13:58:46
да

Dmitry
20.09.2016
14:00:44
foreach (x; Fields!A)
{
writeln(x);
}
ругается на writeln:
Error: cannot pass type string as a function argument

Grigirii
20.09.2016
14:02:21
ну да, x - тип, а не значение. если хочешь итерироваться по именам полей юзай FieldNameTuple
что интересно, на старом dmd компилится и работает в рантайме

Dmitry
20.09.2016
14:03:26
а так можно?
foreach (x; (Fields!A).tupleof)
на старом это на каком?

Grigirii
20.09.2016
14:04:03
v2.070.0

Google

Dmitry
20.09.2016
14:08:30
а почему этот вариант не работает то?
writeln(to!string(x));
Ведь под идее у типа есть строковое представление
а он ругается: Error: cannot pass type string as a function argument
вариант с FieldNameTuple работает
м... а как вообще типы представляются? как я понял у них нет строкового представления

Grigirii
20.09.2016
14:20:06
writeln(A.stringof); //output: A

Dmitry
20.09.2016
14:21:19
и кстати про шаблоны вопрос. Вот допустим возвращаемый тип указан как template как понять какие операции над ним можно сделать?
Как я понимаю можно сделать так:
auto foo = MySuperTemplate!x
и вы получим результат в foo

Grigirii
20.09.2016
14:24:05
в основном по доке. просто есть соглашения на то, что бывает резултатом чего, как например range
ещё может быть указан контракт, если это результат функции
в случае MySuperTemplate!x это чаще всего просто класс, в который можно зайти и посмотреть. Fields здесь скорее исключение

Dmitry
20.09.2016
14:25:07
контракт это что? как он выглядит? в плане куда смотреть чтобы по доке понять

Grigirii
20.09.2016
14:26:10
в доке это обычно словами. контракт это секция in или out в теле функции. в доку вроде не выносится автоматически

Dmitry
20.09.2016
14:26:54
это входные выходные данные ?

Grigirii
20.09.2016
14:26:57
сейчас тулы автокомплита не очень умные, но вообще автокомплит в процессе кодинга в таких ситуациях хорошо помогают
это ограничения на вход и выход
обычно там ограничения на значения, например, что аргумент должен быть сортированным массивом, а не чем попало. это дока и проверка в дебажной сборке. про них есть глава в любой книге
в Александреску это "Контрактное программирование"

Dmitry
20.09.2016
14:29:04
понял, спасибо

Sergey
21.09.2016
06:52:27
Здравствуйте.
Кто-нибудь сталкивался с функцией move для структур?
Наткнулся на странную ситуацию, которую никак не могу понять

Max
21.09.2016
06:58:23
Саму ситуацию-то опиши

Sergey
21.09.2016
07:00:02
сейчас

Google


Sergey
21.09.2016
07:01:14
import std.stdio;
import std.conv;
import std.algorithm;
void main()
{
Point p1 = Point(10,5);
Point p2 = p1;
p1.system.name = "B";
writeln("p1 = ", p1);
writeln("p2 = ", p2);
writeln("---");
write("p2 ");
AnalyzePoint(move(p2));
writeln("p2 init = ", p2);
//Point(0, 0, B) - судя по всему, за исходное значение для system
//берется переданное при Point p2 = p1; т.е. оно было у p2
//до вызова this(this)
//далее видно, что p2.system указывает на тот же объект, что и p1.system
p1.system.name = "C";
writeln("p2 =", p2);
}
void AnalyzePoint(Point p)
{
write("moved ");
writeln(p);
}
struct Point
{
int x;
int y;
//
System system=new System("A");
this(this)
{
system = system.dup;
}
}
class System
{
string name;
this(string name)
{
this.name= name;
}
this()
{
this("Default");
}
override string toString()
{
return name;
}
System dup()
{
return new System(name);
}
}
p1 = Point(10, 5, B)
p2 = Point(10, 5, A)
—-
p2 moved Point(10, 5, A)
p2 init = Point(0, 0, B)
p2 =Point(0, 0, C)
пример синтетический
Одним из полей структуры является объект класса.
для полного копирования структуры, используется конструктор this(this)
После копирования объекта структуры, убеждаюсь, что p1 и p2 независимы.
Затем перемещаю объект структуры в функцию AnalyzePoint(move(p2));
оставшийся идентификатор p2 в теле main должен быть заново инициализирован, поэтому я ожидаю если не p2.system.name == “A”, то хотябы p2.system == null
но вижу, то, что описал в комментарии в коде


Max
21.09.2016
07:21:17
Почитай про .init – после вызова move восстанавливаются дефолтные значения для структуры, без вызова конструктора

Sergey
21.09.2016
07:22:10
читать-то я читал. Не могу понять, почему дефолтным значением структуры стало значение, переданное при копировании
p2 init = Point(0, 0, B)
вот это значение B - его нигде нет в дефолтах. Его я проставил для p1
p1.system.name = "B";
перед копированием Point p2 = p1;
т.е. дефолтным для p2.system внезапно стало значение, которое было скопировано из p1
подправил описание. Написано сумбурно, попытаюсь еще раз соль выделить:
Вот, допустим, такая структура
struct Point
{
int x;
int y=10;
System system=new System("A");
....
}
тогда, вроде бы, всегда результатом init должно становиться
x==0, y==10, system.name =="А"
в моем, получилось system.name =="B", и ранее я написал, откуда взялось это значение. Непонятно, почему оно взялось

Admin
ERROR: S client not available

Oleg
21.09.2016
08:04:51
в последнем варианте есть косячок
там выходит, что ты создаёшь память для system и её же меняешь
заново она не создаётся

Sergey
21.09.2016
08:10:26
честно сказать, не понял, о чем речь

Oleg
21.09.2016
08:12:39
1 сек
import std.stdio;
class Sys
{
string name;
this(string name) { this.name = name; }
override string toString() { return "Sys("~name~")"; }
}
struct A
{
int x=10;
Sys sys = new Sys("in struct");
this(this)
{
sys = new Sys(sys.name);
}
}
void main()
{
A a;
A b;
writeln(a);
writeln(b);
a.sys.name = "xxx";
writeln();
writeln(a);
writeln(b);
}
на момент последнего вывода sys у 'a' и 'b' один и тот же

Sergey
21.09.2016
08:14:08
в данном примере - да
но у меня-то нет

Oleg
21.09.2016
08:14:29
struct Point
{
int x;
int y=10;
System system=new System("A");
....
}

Google

Sergey
21.09.2016
08:14:53
это просто пример, в котором есть "..."
обращал внимание на дефолтные значения
а тело структуры опустил
но в рабочем исходнике есть this(this)

Oleg
21.09.2016
08:15:45
я про инициализацию полей структуры

Sergey
21.09.2016
08:16:20
вот соответсвующий кусок кода
struct Point
{
int x;
int y;
//
System system=new System("A");
this(this)
{
system = system.dup;
}
}

Oleg
21.09.2016
08:16:45
если класс создаётся не в конструкторе, а как init значение, он будет разделён между всеми структурами

Sergey
21.09.2016
08:16:59
соответсвенно, при копировании объекта этой структуры, будет объект класса будет клонирован

Oleg
21.09.2016
08:17:23
метод dup переопределён в классе?
ну хотя не работало бы иначе

Sergey
21.09.2016
08:17:47
да, переопределен

Oleg
21.09.2016
08:18:57
по всей видимости move не копирует объект
всмысле не вызывает конструктор копирования

Sergey
21.09.2016
08:19:23
да. в этом его смысл
но значение p2 появилось ранее в результате копирования
затем уже было перемещено в функцию с помощью move
а для идентификатора p2 в main была вызвана Init (т.е. новый объект создан), насколько я понял из описания move

Oleg
21.09.2016
08:31:05
init значение для поля не новый класс, а старый, созданный в самом начале
это же адресс
там вызывается memcpy для объектов
и потом в один из объектов присваивается init

Sergey
21.09.2016
08:34:24
можно так выразиться: когда я копирую объект структуры, то его init значения переписываются?