www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - this(T...) not called in struct constructor

reply Timothee Cour <thelastmammoth gmail.com> writes:
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)
}
Sep 17 2013
next sibling parent reply "monarch_dodra" <monarchdodra gmail.com> writes:
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.
Sep 18 2013
parent "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Wed, Sep 18, 2013 at 10:12:04AM +0200, monarch_dodra wrote:
 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,
[...] Note that this only applies to structs. Classes have default ctors. T -- Programming is not just an act of telling a computer what to do: it is also an act of telling other programmers what you wished the computer to do. Both are important, and the latter deserves care. -- Andrew Morton
Sep 18 2013
prev sibling parent "Gary Willoughby" <dev nomad.so> writes:
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);
Sep 18 2013