2

Suppose I have the following struct:

import std.stdio;
struct A
{
    this (int arg = 1) {
        writeln("Correct constructor");
    }

    this(); 
}

How to use the default value of the constructor?

The

void main()
{
            A a = A();
}

...produces Error: constructor app.A.this is not callable because it is annotated with @disable. If I remove @disable attribute from default constructor, I would not get my own constructor executed.

And, why structs aren't allowed to have custom default constructor anyway?

2 Answers 2

2

I don't know what the deal is with struct ctors, but you could cheat and try overloading static opCall:

import std.stdio;
struct A {
    static auto opCall() {
        writeln("Correct constructor");
        auto a = typeof(this).init;
        return a;
    };
};

void main() {
    A a = A();
};
Sign up to request clarification or add additional context in comments.

3 Comments

That appears to be working. How much cheating it is? Should I expect any side-effects? E.g. I noticed, that when I replace the line in main with A a = A.init the static opCall doesn't get called, but that is no issue with me.
@AdamRyczkowski: my main concern would be that A.__ctor doesn't exist with this approach, which could interfere with some introspection techniques. I honestly don't have much experience with static opCall, but I suspect it will work fine for most use-cases.
Also, as you noted, .init will never call a function, as it compiles to a simple mov or rep movs (x86) to write the default field values.
1

You should not implement the default struct constructor (here is why: Why can I not implement default constructors for structs in D?).

Remove the this(); line in your code. You do not need it.

If you want some specific value to be your default one, just make it at module level and use it throughout your application. Like in the following example:

import std.stdio;

struct A {
  int a;
  int b;

  this (int arg = 1) {
     a = arg;
     // writeln("Correct constructor");
  }

}

immutable(A) defA = A(5);

void main() {
  A a1 = A(2);
  writeln(a1); // output: A(2, 0)

  // Or, init all to defaults
  A a2 = A.init;
  writeln(a2); // output: A(0, 0)
  A a3 = A();  // same as A.init, as you can see
  writeln(a3); // output: A(0, 0)

  A a4 = defA; // Let's use our "default" value
  a4.b = 10;
  writeln(a4); // output: A(5, 10)
}

2 Comments

Nope. It calls the "Correct construcor" only once, on second invocation (A a2 = A(2)). The first one calls the default constructor, that initializes everything with zeroes and never executes custom code.
The first one is the struct initialiser. I did not say it will execute the constructor with the default parameter. The second one does. I will edit my post to avoid this misunderstanding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.