On Monday, 5 October 2015 at 19:07:20 UTC, Meta wrote:
On Monday, 5 October 2015 at 17:19:09 UTC, Gary Willoughby
wrote:
This can be shortened to:
import std.stdio;
import std.typecons;
class A
{
string name;
this(string name)
{
this.name = name;
}
void hello()
{
writeln("Hello, ", this.name);
}
}
void main()
{
auto a = scoped!A("Foo");
a.hello();
}
There's a critical flaw in `scoped`. Observe:
import std.stdio;
import std.typecons;
class A
{
string name;
this(string name)
{
this.name = name;
writeln("Creating A");
}
~this()
{
writeln("Destroying A");
}
void hello()
{
writeln("Hello, ", this.name);
}
}
void main()
{
auto a1 = scoped!A("Foo");
a1.hello();
A a2 = scoped!A("Foo");
a2.hello();
}
The output:
Creating A
Hello, Foo
Creating A
Destroying A
Destroying A
object.Error: Access Violation
----
import std.stdio;
struct Scoped(T) {
void[__traits(classInstanceSize, T)] buf = void;
this(Args...)(auto ref Args args) {
this.buf = typeid(T).init[];
(cast(T) this.buf.ptr).__ctor(args);
}
~this() {
.destroy(this.get());
}
T get() {
return cast(T) this.buf.ptr;
}
alias get this;
}
auto scoped(T, Args...)(auto ref Args args) {
return Scoped!T(args);
}
class A
{
string name;
this(string name)
{
this.name = name;
writeln("Creating A");
}
~this()
{
writeln("Destroying A");
}
void hello()
{
writeln("Hello, ", this.name);
}
}
void main() {
auto a1 = scoped!A("Foo");
a1.hello();
auto a2 = scoped!A("Bar");
a2.hello();
}
----
Application output:
Creating A
Hello, Foo
Creating A
Hello, Bar
Destroying A
Destroying A