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

Reply via email to