Thread overview | |||||
---|---|---|---|---|---|
|
December 11, 2013 writeln calls postblits constructor four times before print | ||||
---|---|---|---|---|
| ||||
Code: module vector; import std.stdio; import std.traits; struct SVector(size_t dim, T = float) { private: T[dim] _arr; public: alias dim dimension; alias dim size; this(this) { debug(SVector) writeln("postblit constructor"); } this(const T[dim] arr) { debug(SVector) writeln("constructor from static array"); _arr = arr; } this(ref const T[dim] arr) { debug(SVector) writeln("constructor from ref static array"); _arr = arr; } this(const(T)[] arr) { debug(SVector) writeln("constructor from slice"); assert(arr.length == dim); _arr = arr; } ref SVector opAssign(const SVector other) { debug(SVector) writeln("assign other vector"); _arr = other._arr; return this; } ref SVector opAssign(ref const SVector other) { debug(SVector) writeln("assign other ref vector"); _arr = other._arr; return this; } ref SVector opAssign(const T[dim] arr) { debug(SVector) writeln("assign static array"); _arr = arr; return this; } ref SVector opAssign(ref const T[dim] arr) { debug(SVector) writeln("assign ref static array"); _arr = arr; return this; } ref SVector opAssign(const(T)[] arr) { debug(SVector) writeln("assign dynamic array"); assert(arr.length == dim); _arr = arr; return this; } T[] opSlice() { return _arr[]; } T[] opSlice(size_t begin, size_t end) { return _arr[begin..end]; } const(T)[] opSlice() const { return _arr[]; } const(T)[] opSlice(size_t begin, size_t end) const { return _arr[begin..end]; } T opIndex(size_t i) const { return _arr[i]; } T opIndexAssign(const(T) value, size_t i) { return _arr[i] = value; } size_t opDollar() const { return dim; } } unittest { alias float scalar; alias SVector!(3, scalar) vec; vec v = [1,2,3]; writeln(v); } int main() { return 0; } This type has simple postblit constructor, but what if it needs to allocate memory? Simple example is this._arr = _arr.dup if we would use dynamic array. We have really big overhead here. By the way, why does writeln able to print this struct? It has no toString() method and its data is private. How does writeln have access to it? |
December 11, 2013 Re: writeln calls postblits constructor four times before print | ||||
---|---|---|---|---|
| ||||
Posted in reply to FreeSlave | FreeSlave:
> By the way, why does writeln able to print this struct? It has no toString() method and its data is private. How does writeln have access to it?
writeln is able to print structs that don't have a toString, this is very handy in most cases. When you don't want it, there's @disable, this doesn't link:
struct Foo {
int x;
//string toString() { return "x"; }
@disable string toString();
}
void main() {
import std.stdio;
Foo f = Foo(10);
writeln(f);
}
In theory this should be caught by writefln constraint before the linker. Probably I can turn this into a small enhancement request.
Bye,
bearophile
|
December 11, 2013 Re: writeln calls postblits constructor four times before print | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | > In theory this should be caught by writefln constraint before the linker. Probably I can turn this into a small enhancement request.
On the other hand if you care about this it's better for you to open the ER.
Bye,
bearophile
|
Copyright © 1999-2021 by the D Language Foundation