Thread overview
this(T...) not called in struct constructor
Sep 18, 2013
Timothee Cour
Sep 18, 2013
monarch_dodra
Sep 18, 2013
Gary Willoughby
September 18, 2013
This may have been discussed before, but I'm not sure whether this is a bug or not. In any case it's a bit confusing.

struct Foo2{
  this(T...)(T args){
    assert(0);
  }
}

void main(){
  auto a2=Foo2();//doesn't call assert(0) (ie this(T...) not called)
}


September 18, 2013
On Wednesday, 18 September 2013 at 05:28:41 UTC, Timothee Cour wrote:
> This may have been discussed before, but I'm not sure whether this is a bug
> or not. In any case it's a bit confusing.
>
> struct Foo2{
>   this(T...)(T args){
>     assert(0);
>   }
> }
>
> void main(){
>   auto a2=Foo2();//doesn't call assert(0) (ie this(T...) not called)
> }

There is no "argument-less constructor" in D. "Struct()" is just shorthand for "Struct.init" (bar a few exceptional exceptions: @disabled this() and static opCall).

AFAIK, D decided to not have "default" constructors, as it goes against a few other features (compile time known init state, compile time statics). However, not having a constructor which has "0 arguments" is a gratuitous historical limitation.

Chances are it won't change any time soon (or ever).

Workarounds include:
//----
//
Calling "__ctor" explicitly:
Foo2 foo2;
foo2.__ctor();
(IMO god awful solution)

//----
//
Using static opCall instead of constructor:
struct Foo2
{
  Foo2 static opCall(T...)(T args)
  {
    Foo2 ret;
    //Do something.
    return ret;
  }
}
Foo2 foo2 = Foo2(); //Calls opCall
A bit hackish, but works. Unfortunately, this is not a "construction" sequence, so you won't be able to use it with emplace, for example.

//----
//
A non-member free function. Similar to static opCall, but a bit less hackish. Just create a free function (usually named the same as your struct, but lowercased).
This is also used a lot in Phobos, as it can prevent direct use of the struct:

private struct Foo2Result
{

}

public auto foo2(T...)(T args)
{
    Foo2 ret;
    //Do something.
    return ret;
}

auto myFoo2 = foo2(); //Calls the function.
September 18, 2013
On Wednesday, 18 September 2013 at 05:28:41 UTC, Timothee Cour wrote:
> This may have been discussed before, but I'm not sure whether this is a bug
> or not. In any case it's a bit confusing.
>
> struct Foo2{
>   this(T...)(T args){
>     assert(0);
>   }
> }
>
> void main(){
>   auto a2=Foo2();//doesn't call assert(0) (ie this(T...) not called)
> }

You are not passing a value to the constructor. Use auto a2=Foo2(1);